mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-30 05:58:38 +00:00
Support shared media / pins for sublists.
This commit is contained in:
parent
ffe6786ad1
commit
dfc1ec3ccf
@ -2978,17 +2978,27 @@ void ApiWrap::resolveJumpToDate(
|
|||||||
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
||||||
if (const auto peer = chat.peer()) {
|
if (const auto peer = chat.peer()) {
|
||||||
const auto topic = chat.topic();
|
const auto topic = chat.topic();
|
||||||
const auto rootId = topic ? topic->rootId() : 0;
|
const auto sublist = chat.sublist();
|
||||||
resolveJumpToHistoryDate(peer, rootId, date, std::move(callback));
|
const auto rootId = topic ? topic->rootId() : MsgId();
|
||||||
|
const auto monoforumPeerId = sublist
|
||||||
|
? sublist->sublistPeer()->id
|
||||||
|
: PeerId();
|
||||||
|
resolveJumpToHistoryDate(
|
||||||
|
peer,
|
||||||
|
rootId,
|
||||||
|
monoforumPeerId,
|
||||||
|
date,
|
||||||
|
std::move(callback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void ApiWrap::requestMessageAfterDate(
|
void ApiWrap::requestMessageAfterDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
const QDate &date,
|
PeerId monoforumPeerId,
|
||||||
Callback &&callback) {
|
const QDate &date,
|
||||||
|
Callback &&callback) {
|
||||||
// API returns a message with date <= offset_date.
|
// API returns a message with date <= offset_date.
|
||||||
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
|
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
|
||||||
// This should give us the first message with date >= desired_date.
|
// This should give us the first message with date >= desired_date.
|
||||||
@ -3011,7 +3021,7 @@ void ApiWrap::requestMessageAfterDate(
|
|||||||
return &messages.vmessages().v;
|
return &messages.vmessages().v;
|
||||||
};
|
};
|
||||||
const auto list = result.match([&](
|
const auto list = result.match([&](
|
||||||
const MTPDmessages_messages &data) {
|
const MTPDmessages_messages &data) {
|
||||||
return handleMessages(data);
|
return handleMessages(data);
|
||||||
}, [&](const MTPDmessages_messagesSlice &data) {
|
}, [&](const MTPDmessages_messagesSlice &data) {
|
||||||
return handleMessages(data);
|
return handleMessages(data);
|
||||||
@ -3054,6 +3064,18 @@ void ApiWrap::requestMessageAfterDate(
|
|||||||
MTP_int(maxId),
|
MTP_int(maxId),
|
||||||
MTP_int(minId),
|
MTP_int(minId),
|
||||||
MTP_long(historyHash)));
|
MTP_long(historyHash)));
|
||||||
|
} else if (monoforumPeerId) {
|
||||||
|
send(MTPmessages_GetSavedHistory(
|
||||||
|
MTP_flags(MTPmessages_GetSavedHistory::Flag::f_parent_peer),
|
||||||
|
peer->input,
|
||||||
|
session().data().peer(monoforumPeerId)->input,
|
||||||
|
MTP_int(offsetId),
|
||||||
|
MTP_int(offsetDate),
|
||||||
|
MTP_int(addOffset),
|
||||||
|
MTP_int(limit),
|
||||||
|
MTP_int(maxId),
|
||||||
|
MTP_int(minId),
|
||||||
|
MTP_long(historyHash)));
|
||||||
} else {
|
} else {
|
||||||
send(MTPmessages_GetHistory(
|
send(MTPmessages_GetHistory(
|
||||||
peer->input,
|
peer->input,
|
||||||
@ -3070,28 +3092,41 @@ void ApiWrap::requestMessageAfterDate(
|
|||||||
void ApiWrap::resolveJumpToHistoryDate(
|
void ApiWrap::resolveJumpToHistoryDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
const QDate &date,
|
const QDate &date,
|
||||||
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
||||||
if (const auto channel = peer->migrateTo()) {
|
if (const auto channel = peer->migrateTo()) {
|
||||||
return resolveJumpToHistoryDate(
|
return resolveJumpToHistoryDate(
|
||||||
channel,
|
channel,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
date,
|
date,
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
}
|
}
|
||||||
const auto jumpToDateInPeer = [=] {
|
const auto jumpToDateInPeer = [=] {
|
||||||
requestMessageAfterDate(peer, topicRootId, date, [=](MsgId itemId) {
|
requestMessageAfterDate(
|
||||||
callback(peer, itemId);
|
peer,
|
||||||
});
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
|
date,
|
||||||
|
[=](MsgId itemId) { callback(peer, itemId); });
|
||||||
};
|
};
|
||||||
if (const auto chat = topicRootId ? nullptr : peer->migrateFrom()) {
|
const auto migrated = (topicRootId || monoforumPeerId)
|
||||||
requestMessageAfterDate(chat, 0, date, [=](MsgId itemId) {
|
? nullptr
|
||||||
if (itemId) {
|
: peer->migrateFrom();
|
||||||
callback(chat, itemId);
|
if (migrated) {
|
||||||
} else {
|
requestMessageAfterDate(
|
||||||
jumpToDateInPeer();
|
migrated,
|
||||||
}
|
MsgId(),
|
||||||
});
|
PeerId(),
|
||||||
|
date,
|
||||||
|
[=](MsgId itemId) {
|
||||||
|
if (itemId) {
|
||||||
|
callback(migrated, itemId);
|
||||||
|
} else {
|
||||||
|
jumpToDateInPeer();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
jumpToDateInPeer();
|
jumpToDateInPeer();
|
||||||
}
|
}
|
||||||
@ -3140,12 +3175,14 @@ void ApiWrap::requestHistory(
|
|||||||
void ApiWrap::requestSharedMedia(
|
void ApiWrap::requestSharedMedia(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
MsgId messageId,
|
MsgId messageId,
|
||||||
SliceType slice) {
|
SliceType slice) {
|
||||||
const auto key = SharedMediaRequest{
|
const auto key = SharedMediaRequest{
|
||||||
peer,
|
peer,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
type,
|
type,
|
||||||
messageId,
|
messageId,
|
||||||
slice,
|
slice,
|
||||||
@ -3157,6 +3194,7 @@ void ApiWrap::requestSharedMedia(
|
|||||||
const auto prepared = Api::PrepareSearchRequest(
|
const auto prepared = Api::PrepareSearchRequest(
|
||||||
peer,
|
peer,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
type,
|
type,
|
||||||
QString(),
|
QString(),
|
||||||
messageId,
|
messageId,
|
||||||
@ -3179,7 +3217,12 @@ void ApiWrap::requestSharedMedia(
|
|||||||
messageId,
|
messageId,
|
||||||
slice,
|
slice,
|
||||||
result);
|
result);
|
||||||
sharedMediaDone(peer, topicRootId, type, std::move(parsed));
|
sharedMediaDone(
|
||||||
|
peer,
|
||||||
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
|
type,
|
||||||
|
std::move(parsed));
|
||||||
finish();
|
finish();
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
_sharedMediaRequests.remove(key);
|
_sharedMediaRequests.remove(key);
|
||||||
@ -3192,16 +3235,19 @@ void ApiWrap::requestSharedMedia(
|
|||||||
void ApiWrap::sharedMediaDone(
|
void ApiWrap::sharedMediaDone(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
Api::SearchResult &&parsed) {
|
Api::SearchResult &&parsed) {
|
||||||
const auto topic = peer->forumTopicFor(topicRootId);
|
const auto topic = peer->forumTopicFor(topicRootId);
|
||||||
if (topicRootId && !topic) {
|
const auto sublist = peer->monoforumSublistFor(monoforumPeerId);
|
||||||
|
if ((topicRootId && !topic) || (monoforumPeerId && !sublist)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto hasMessages = !parsed.messageIds.empty();
|
const auto hasMessages = !parsed.messageIds.empty();
|
||||||
_session->storage().add(Storage::SharedMediaAddSlice(
|
_session->storage().add(Storage::SharedMediaAddSlice(
|
||||||
peer->id,
|
peer->id,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
type,
|
type,
|
||||||
std::move(parsed.messageIds),
|
std::move(parsed.messageIds),
|
||||||
parsed.noSkipRange,
|
parsed.noSkipRange,
|
||||||
@ -3212,6 +3258,9 @@ void ApiWrap::sharedMediaDone(
|
|||||||
if (topic) {
|
if (topic) {
|
||||||
topic->setHasPinnedMessages(true);
|
topic->setHasPinnedMessages(true);
|
||||||
}
|
}
|
||||||
|
if (sublist) {
|
||||||
|
sublist->setHasPinnedMessages(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3245,16 +3294,12 @@ void ApiWrap::sendAction(const SendAction &action) {
|
|||||||
&& !action.options.shortcutId
|
&& !action.options.shortcutId
|
||||||
&& !action.replaceMediaOf) {
|
&& !action.replaceMediaOf) {
|
||||||
const auto topicRootId = action.replyTo.topicRootId;
|
const auto topicRootId = action.replyTo.topicRootId;
|
||||||
const auto monoforumPeerId = action.replyTo.monoforumPeerId;
|
|
||||||
const auto topic = topicRootId
|
const auto topic = topicRootId
|
||||||
? action.history->peer->forumTopicFor(topicRootId)
|
? action.history->peer->forumTopicFor(topicRootId)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto monoforum = monoforumPeerId
|
const auto monoforumPeerId = action.replyTo.monoforumPeerId;
|
||||||
? action.history->peer->monoforum()
|
const auto sublist = monoforumPeerId
|
||||||
: nullptr;
|
? action.history->peer->monoforumSublistFor(monoforumPeerId)
|
||||||
const auto sublist = monoforum
|
|
||||||
? monoforum->sublistLoaded(
|
|
||||||
action.history->owner().peer(monoforumPeerId))
|
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (topic) {
|
if (topic) {
|
||||||
topic->readTillEnd();
|
topic->readTillEnd();
|
||||||
|
@ -289,6 +289,7 @@ public:
|
|||||||
void requestSharedMedia(
|
void requestSharedMedia(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
Storage::SharedMediaType type,
|
Storage::SharedMediaType type,
|
||||||
MsgId messageId,
|
MsgId messageId,
|
||||||
SliceType slice);
|
SliceType slice);
|
||||||
@ -505,18 +506,21 @@ private:
|
|||||||
void resolveJumpToHistoryDate(
|
void resolveJumpToHistoryDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
const QDate &date,
|
const QDate &date,
|
||||||
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void requestMessageAfterDate(
|
void requestMessageAfterDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
const QDate &date,
|
const QDate &date,
|
||||||
Callback &&callback);
|
Callback &&callback);
|
||||||
|
|
||||||
void sharedMediaDone(
|
void sharedMediaDone(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
Api::SearchResult &&parsed);
|
Api::SearchResult &&parsed);
|
||||||
void globalMediaDone(
|
void globalMediaDone(
|
||||||
@ -665,6 +669,7 @@ private:
|
|||||||
struct SharedMediaRequest {
|
struct SharedMediaRequest {
|
||||||
not_null<PeerData*> peer;
|
not_null<PeerData*> peer;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
SharedMediaType mediaType = {};
|
SharedMediaType mediaType = {};
|
||||||
MsgId aroundId = 0;
|
MsgId aroundId = 0;
|
||||||
SliceType sliceType = {};
|
SliceType sliceType = {};
|
||||||
|
@ -24,10 +24,15 @@ namespace {
|
|||||||
[[nodiscard]] bool IsOldForPin(
|
[[nodiscard]] bool IsOldForPin(
|
||||||
MsgId id,
|
MsgId id,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId) {
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId) {
|
||||||
const auto normal = peer->migrateToOrMe();
|
const auto normal = peer->migrateToOrMe();
|
||||||
const auto migrated = normal->migrateFrom();
|
const auto migrated = normal->migrateFrom();
|
||||||
const auto top = Data::ResolveTopPinnedId(normal, topicRootId, migrated);
|
const auto top = Data::ResolveTopPinnedId(
|
||||||
|
normal,
|
||||||
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
|
migrated);
|
||||||
if (!top) {
|
if (!top) {
|
||||||
return false;
|
return false;
|
||||||
} else if (peer == migrated) {
|
} else if (peer == migrated) {
|
||||||
@ -53,7 +58,14 @@ void PinMessageBox(
|
|||||||
const auto peer = item->history()->peer;
|
const auto peer = item->history()->peer;
|
||||||
const auto msgId = item->id;
|
const auto msgId = item->id;
|
||||||
const auto topicRootId = item->topic() ? item->topicRootId() : MsgId();
|
const auto topicRootId = item->topic() ? item->topicRootId() : MsgId();
|
||||||
const auto pinningOld = IsOldForPin(msgId, peer, topicRootId);
|
const auto monoforumPeerId = item->history()->peer->amMonoforumAdmin()
|
||||||
|
? item->sublistPeerId()
|
||||||
|
: PeerId();
|
||||||
|
const auto pinningOld = IsOldForPin(
|
||||||
|
msgId,
|
||||||
|
peer,
|
||||||
|
topicRootId,
|
||||||
|
monoforumPeerId);
|
||||||
const auto state = box->lifetime().make_state<State>();
|
const auto state = box->lifetime().make_state<State>();
|
||||||
const auto api = box->lifetime().make_state<MTP::Sender>(
|
const auto api = box->lifetime().make_state<MTP::Sender>(
|
||||||
&peer->session().mtp());
|
&peer->session().mtp());
|
||||||
|
@ -847,6 +847,7 @@ bool OpenMediaTimestamp(
|
|||||||
document,
|
document,
|
||||||
context,
|
context,
|
||||||
context ? context->topicRootId() : MsgId(0),
|
context ? context->topicRootId() : MsgId(0),
|
||||||
|
context ? context->sublistPeerId() : PeerId(0),
|
||||||
false,
|
false,
|
||||||
time));
|
time));
|
||||||
} else if (document->isSong() || document->isVoiceMessage()) {
|
} else if (document->isSong() || document->isVoiceMessage()) {
|
||||||
|
@ -187,7 +187,8 @@ void ResolveDocument(
|
|||||||
Window::SessionController *controller,
|
Window::SessionController *controller,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
MsgId topicRootId) {
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId) {
|
||||||
if (document->isNull()) {
|
if (document->isNull()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -202,7 +203,7 @@ void ResolveDocument(
|
|||||||
controller->openDocument(
|
controller->openDocument(
|
||||||
document,
|
document,
|
||||||
true,
|
true,
|
||||||
{ msgId, topicRootId });
|
{ msgId, topicRootId, monoforumPeerId });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ void ResolveDocument(
|
|||||||
Window::SessionController *controller,
|
Window::SessionController *controller,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
MsgId topicRootId);
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId);
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
@ -72,7 +72,10 @@ Forum::~Forum() {
|
|||||||
auto &changes = session().changes();
|
auto &changes = session().changes();
|
||||||
const auto peerId = _history->peer->id;
|
const auto peerId = _history->peer->id;
|
||||||
for (const auto &[rootId, topic] : _topics) {
|
for (const auto &[rootId, topic] : _topics) {
|
||||||
storage.unload(Storage::SharedMediaUnloadThread(peerId, rootId));
|
storage.unload(Storage::SharedMediaUnloadThread(
|
||||||
|
peerId,
|
||||||
|
rootId,
|
||||||
|
PeerId()));
|
||||||
_history->setForwardDraft(rootId, PeerId(), {});
|
_history->setForwardDraft(rootId, PeerId(), {});
|
||||||
|
|
||||||
const auto raw = topic.get();
|
const auto raw = topic.get();
|
||||||
@ -198,7 +201,8 @@ void Forum::applyTopicDeleted(MsgId rootId) {
|
|||||||
_history->destroyMessagesByTopic(rootId);
|
_history->destroyMessagesByTopic(rootId);
|
||||||
session().storage().unload(Storage::SharedMediaUnloadThread(
|
session().storage().unload(Storage::SharedMediaUnloadThread(
|
||||||
_history->peer->id,
|
_history->peer->id,
|
||||||
rootId));
|
rootId,
|
||||||
|
PeerId()));
|
||||||
_history->setForwardDraft(rootId, PeerId(), {});
|
_history->setForwardDraft(rootId, PeerId(), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +152,7 @@ rpl::producer<SparseIdsMergedSlice> HistoryMergedViewer(
|
|||||||
auto createSimpleViewer = [=](
|
auto createSimpleViewer = [=](
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SparseIdsSlice::Key simpleKey,
|
SparseIdsSlice::Key simpleKey,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter) {
|
int limitAfter) {
|
||||||
@ -161,11 +162,10 @@ rpl::producer<SparseIdsMergedSlice> HistoryMergedViewer(
|
|||||||
return HistoryViewer(chosen, simpleKey, limitBefore, limitAfter);
|
return HistoryViewer(chosen, simpleKey, limitBefore, limitAfter);
|
||||||
};
|
};
|
||||||
const auto peerId = history->peer->id;
|
const auto peerId = history->peer->id;
|
||||||
const auto topicRootId = MsgId();
|
|
||||||
const auto migratedPeerId = migrateFrom ? migrateFrom->id : PeerId(0);
|
const auto migratedPeerId = migrateFrom ? migrateFrom->id : PeerId(0);
|
||||||
using Key = SparseIdsMergedSlice::Key;
|
using Key = SparseIdsMergedSlice::Key;
|
||||||
return SparseIdsMergedSlice::CreateViewer(
|
return SparseIdsMergedSlice::CreateViewer(
|
||||||
Key(peerId, topicRootId, migratedPeerId, universalAroundId),
|
Key(peerId, MsgId(), PeerId(), migratedPeerId, universalAroundId),
|
||||||
limitBefore,
|
limitBefore,
|
||||||
limitAfter,
|
limitAfter,
|
||||||
std::move(createSimpleViewer));
|
std::move(createSimpleViewer));
|
||||||
|
@ -1474,6 +1474,16 @@ Data::SavedMessages *PeerData::monoforum() const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Data::SavedSublist *PeerData::monoforumSublistFor(
|
||||||
|
PeerId sublistPeerId) const {
|
||||||
|
if (!sublistPeerId) {
|
||||||
|
return nullptr;
|
||||||
|
} else if (const auto monoforum = this->monoforum()) {
|
||||||
|
return monoforum->sublistLoaded(owner().peer(sublistPeerId));
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool PeerData::allowsForwarding() const {
|
bool PeerData::allowsForwarding() const {
|
||||||
if (isUser()) {
|
if (isUser()) {
|
||||||
return true;
|
return true;
|
||||||
@ -1807,12 +1817,14 @@ void SetTopPinnedMessageId(
|
|||||||
session.settings().setHiddenPinnedMessageId(
|
session.settings().setHiddenPinnedMessageId(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
0);
|
0);
|
||||||
session.saveSettingsDelayed();
|
session.saveSettingsDelayed();
|
||||||
}
|
}
|
||||||
session.storage().add(Storage::SharedMediaAddExisting(
|
session.storage().add(Storage::SharedMediaAddExisting(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
messageId,
|
messageId,
|
||||||
{ messageId, ServerMaxMsgId }));
|
{ messageId, ServerMaxMsgId }));
|
||||||
@ -1822,22 +1834,25 @@ void SetTopPinnedMessageId(
|
|||||||
FullMsgId ResolveTopPinnedId(
|
FullMsgId ResolveTopPinnedId(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated) {
|
PeerData *migrated) {
|
||||||
const auto slice = peer->session().storage().snapshot(
|
const auto slice = peer->session().storage().snapshot(
|
||||||
Storage::SharedMediaQuery(
|
Storage::SharedMediaQuery(
|
||||||
Storage::SharedMediaKey(
|
Storage::SharedMediaKey(
|
||||||
peer->id,
|
peer->id,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
ServerMaxMsgId - 1),
|
ServerMaxMsgId - 1),
|
||||||
1,
|
1,
|
||||||
1));
|
1));
|
||||||
const auto old = (!topicRootId && migrated)
|
const auto old = (!topicRootId && !monoforumPeerId && migrated)
|
||||||
? migrated->session().storage().snapshot(
|
? migrated->session().storage().snapshot(
|
||||||
Storage::SharedMediaQuery(
|
Storage::SharedMediaQuery(
|
||||||
Storage::SharedMediaKey(
|
Storage::SharedMediaKey(
|
||||||
migrated->id,
|
migrated->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
ServerMaxMsgId - 1),
|
ServerMaxMsgId - 1),
|
||||||
1,
|
1,
|
||||||
@ -1859,22 +1874,25 @@ FullMsgId ResolveTopPinnedId(
|
|||||||
FullMsgId ResolveMinPinnedId(
|
FullMsgId ResolveMinPinnedId(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated) {
|
PeerData *migrated) {
|
||||||
const auto slice = peer->session().storage().snapshot(
|
const auto slice = peer->session().storage().snapshot(
|
||||||
Storage::SharedMediaQuery(
|
Storage::SharedMediaQuery(
|
||||||
Storage::SharedMediaKey(
|
Storage::SharedMediaKey(
|
||||||
peer->id,
|
peer->id,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
1),
|
1),
|
||||||
1,
|
1,
|
||||||
1));
|
1));
|
||||||
const auto old = (!topicRootId && migrated)
|
const auto old = (!topicRootId && !monoforumPeerId && migrated)
|
||||||
? migrated->session().storage().snapshot(
|
? migrated->session().storage().snapshot(
|
||||||
Storage::SharedMediaQuery(
|
Storage::SharedMediaQuery(
|
||||||
Storage::SharedMediaKey(
|
Storage::SharedMediaKey(
|
||||||
migrated->id,
|
migrated->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
1),
|
1),
|
||||||
1,
|
1,
|
||||||
|
@ -38,6 +38,7 @@ class ForumTopic;
|
|||||||
class Session;
|
class Session;
|
||||||
class GroupCall;
|
class GroupCall;
|
||||||
class SavedMessages;
|
class SavedMessages;
|
||||||
|
class SavedSublist;
|
||||||
struct ReactionId;
|
struct ReactionId;
|
||||||
class WallPaper;
|
class WallPaper;
|
||||||
|
|
||||||
@ -260,6 +261,8 @@ public:
|
|||||||
[[nodiscard]] Data::ForumTopic *forumTopicFor(MsgId rootId) const;
|
[[nodiscard]] Data::ForumTopic *forumTopicFor(MsgId rootId) const;
|
||||||
|
|
||||||
[[nodiscard]] Data::SavedMessages *monoforum() const;
|
[[nodiscard]] Data::SavedMessages *monoforum() const;
|
||||||
|
[[nodiscard]] Data::SavedSublist *monoforumSublistFor(
|
||||||
|
PeerId sublistPeerId) const;
|
||||||
|
|
||||||
[[nodiscard]] Data::PeerNotifySettings ¬ify() {
|
[[nodiscard]] Data::PeerNotifySettings ¬ify() {
|
||||||
return _notify;
|
return _notify;
|
||||||
@ -616,10 +619,12 @@ void SetTopPinnedMessageId(
|
|||||||
[[nodiscard]] FullMsgId ResolveTopPinnedId(
|
[[nodiscard]] FullMsgId ResolveTopPinnedId(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated = nullptr);
|
PeerData *migrated = nullptr);
|
||||||
[[nodiscard]] FullMsgId ResolveMinPinnedId(
|
[[nodiscard]] FullMsgId ResolveMinPinnedId(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated = nullptr);
|
PeerData *migrated = nullptr);
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_histories.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_saved_sublist.h"
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
@ -18,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_unread_things.h"
|
#include "history/history_unread_things.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "storage/storage_facade.h"
|
||||||
|
#include "storage/storage_shared_media.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
@ -29,6 +32,7 @@ constexpr auto kListPerPage = 100;
|
|||||||
constexpr auto kListFirstPerPage = 20;
|
constexpr auto kListFirstPerPage = 20;
|
||||||
constexpr auto kLoadedSublistsMinCount = 20;
|
constexpr auto kLoadedSublistsMinCount = 20;
|
||||||
constexpr auto kShowSublistNamesCount = 5;
|
constexpr auto kShowSublistNamesCount = 5;
|
||||||
|
constexpr auto kStalePerRequest = 100;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -50,16 +54,36 @@ SavedMessages::SavedMessages(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SavedMessages::~SavedMessages() {
|
void SavedMessages::clear() {
|
||||||
|
for (const auto &request : base::take(_sublistRequests)) {
|
||||||
|
if (request.second.id != _staleRequestId) {
|
||||||
|
owner().histories().cancelRequest(request.second.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (const auto requestId = base::take(_staleRequestId)) {
|
||||||
|
session().api().request(requestId).cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &storage = session().storage();
|
||||||
auto &changes = session().changes();
|
auto &changes = session().changes();
|
||||||
if (_owningHistory) {
|
if (_owningHistory) {
|
||||||
for (const auto &[peer, sublist] : _sublists) {
|
for (const auto &[peer, sublist] : base::take(_sublists)) {
|
||||||
|
storage.unload(Storage::SharedMediaUnloadThread(
|
||||||
|
_owningHistory->peer->id,
|
||||||
|
MsgId(),
|
||||||
|
peer->id));
|
||||||
_owningHistory->setForwardDraft(MsgId(), peer->id, {});
|
_owningHistory->setForwardDraft(MsgId(), peer->id, {});
|
||||||
|
|
||||||
const auto raw = sublist.get();
|
const auto raw = sublist.get();
|
||||||
|
changes.sublistRemoved(raw);
|
||||||
changes.entryRemoved(raw);
|
changes.entryRemoved(raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_owningHistory = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedMessages::~SavedMessages() {
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SavedMessages::supported() const {
|
bool SavedMessages::supported() const {
|
||||||
@ -108,6 +132,90 @@ SavedSublist *SavedMessages::sublistLoaded(not_null<PeerData*> peer) {
|
|||||||
return (i != end(_sublists)) ? i->second.get() : nullptr;
|
return (i != end(_sublists)) ? i->second.get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SavedMessages::requestSomeStale() {
|
||||||
|
if (_staleRequestId
|
||||||
|
|| (!_offset.id && _loadMoreRequestId)
|
||||||
|
|| _stalePeers.empty()
|
||||||
|
|| !_parentChat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto type = Histories::RequestType::History;
|
||||||
|
auto peers = std::vector<not_null<PeerData*>>();
|
||||||
|
auto peerIds = QVector<MTPInputPeer>();
|
||||||
|
peers.reserve(std::min(int(_stalePeers.size()), kStalePerRequest));
|
||||||
|
peerIds.reserve(std::min(int(_stalePeers.size()), kStalePerRequest));
|
||||||
|
for (auto i = begin(_stalePeers); i != end(_stalePeers);) {
|
||||||
|
const auto peer = *i;
|
||||||
|
i = _stalePeers.erase(i);
|
||||||
|
|
||||||
|
peers.push_back(peer);
|
||||||
|
peerIds.push_back(peer->input);
|
||||||
|
if (peerIds.size() == kStalePerRequest) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (peerIds.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto call = [=] {
|
||||||
|
for (const auto &peer : peers) {
|
||||||
|
finishSublistRequest(peer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto &histories = owner().histories();
|
||||||
|
_staleRequestId = histories.sendRequest(_owningHistory, type, [=](
|
||||||
|
Fn<void()> finish) {
|
||||||
|
using Flag = MTPmessages_GetSavedDialogsByID::Flag;
|
||||||
|
return session().api().request(
|
||||||
|
MTPmessages_GetSavedDialogsByID(
|
||||||
|
MTP_flags(Flag::f_parent_peer),
|
||||||
|
_parentChat->input,
|
||||||
|
MTP_vector<MTPInputPeer>(peerIds))
|
||||||
|
).done([=](const MTPmessages_SavedDialogs &result) {
|
||||||
|
_staleRequestId = 0;
|
||||||
|
applyReceivedSublists(result);
|
||||||
|
call();
|
||||||
|
finish();
|
||||||
|
}).fail([=] {
|
||||||
|
_staleRequestId = 0;
|
||||||
|
call();
|
||||||
|
finish();
|
||||||
|
}).send();
|
||||||
|
});
|
||||||
|
for (const auto &peer : peers) {
|
||||||
|
_sublistRequests[peer].id = _staleRequestId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedMessages::finishSublistRequest(not_null<PeerData*> peer) {
|
||||||
|
if (const auto request = _sublistRequests.take(peer)) {
|
||||||
|
for (const auto &callback : request->callbacks) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SavedMessages::requestSublist(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<void()> done) {
|
||||||
|
if (!_parentChat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto &request = _sublistRequests[peer];
|
||||||
|
if (done) {
|
||||||
|
request.callbacks.push_back(std::move(done));
|
||||||
|
}
|
||||||
|
if (!request.id
|
||||||
|
&& _stalePeers.emplace(peer).second
|
||||||
|
&& (_stalePeers.size() == 1)) {
|
||||||
|
crl::on_main(&session(), [peer = _parentChat] {
|
||||||
|
if (const auto monoforum = peer->monoforum()) {
|
||||||
|
monoforum->requestSomeStale();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<> SavedMessages::chatsListChanges() const {
|
rpl::producer<> SavedMessages::chatsListChanges() const {
|
||||||
return _chatsListChanges.events();
|
return _chatsListChanges.events();
|
||||||
}
|
}
|
||||||
@ -146,18 +254,28 @@ void SavedMessages::sendLoadMore() {
|
|||||||
MTP_flags(Flag::f_exclude_pinned
|
MTP_flags(Flag::f_exclude_pinned
|
||||||
| (_parentChat ? Flag::f_parent_peer : Flag(0))),
|
| (_parentChat ? Flag::f_parent_peer : Flag(0))),
|
||||||
_parentChat ? _parentChat->input : MTPInputPeer(),
|
_parentChat ? _parentChat->input : MTPInputPeer(),
|
||||||
MTP_int(_offsetDate),
|
MTP_int(_offset.date),
|
||||||
MTP_int(_offsetId),
|
MTP_int(_offset.id),
|
||||||
_offsetPeer ? _offsetPeer->input : MTP_inputPeerEmpty(),
|
_offset.peer ? _offset.peer->input : MTP_inputPeerEmpty(),
|
||||||
MTP_int(_offsetId ? kListPerPage : kListFirstPerPage),
|
MTP_int(_offset.id ? kListPerPage : kListFirstPerPage),
|
||||||
MTP_long(0)) // hash
|
MTP_long(0)) // hash
|
||||||
).done([=](const MTPmessages_SavedDialogs &result) {
|
).done([=](const MTPmessages_SavedDialogs &result) {
|
||||||
apply(result, false);
|
const auto applied = applyReceivedSublists(result);
|
||||||
|
if (applied.allLoaded || _offset == applied.offset) {
|
||||||
|
_chatsList.setLoaded();
|
||||||
|
} else if (_offset.date > 0 && applied.offset.date > _offset.date) {
|
||||||
|
LOG(("API Error: Bad order in messages.savedDialogs."));
|
||||||
|
_chatsList.setLoaded();
|
||||||
|
} else {
|
||||||
|
_offset = applied.offset;
|
||||||
|
}
|
||||||
|
_loadMoreRequestId = 0;
|
||||||
_chatsListChanges.fire({});
|
_chatsListChanges.fire({});
|
||||||
if (_chatsList.loaded()) {
|
if (_chatsList.loaded()) {
|
||||||
_chatsListLoadedEvents.fire({});
|
_chatsListLoadedEvents.fire({});
|
||||||
}
|
}
|
||||||
reorderLastSublists();
|
reorderLastSublists();
|
||||||
|
requestSomeStale();
|
||||||
}).fail([=](const MTP::Error &error) {
|
}).fail([=](const MTP::Error &error) {
|
||||||
if (error.type() == u"SAVED_DIALOGS_UNSUPPORTED"_q) {
|
if (error.type() == u"SAVED_DIALOGS_UNSUPPORTED"_q) {
|
||||||
markUnsupported();
|
markUnsupported();
|
||||||
@ -174,7 +292,9 @@ void SavedMessages::loadPinned() {
|
|||||||
_pinnedRequestId = _owner->session().api().request(
|
_pinnedRequestId = _owner->session().api().request(
|
||||||
MTPmessages_GetPinnedSavedDialogs()
|
MTPmessages_GetPinnedSavedDialogs()
|
||||||
).done([=](const MTPmessages_SavedDialogs &result) {
|
).done([=](const MTPmessages_SavedDialogs &result) {
|
||||||
apply(result, true);
|
_pinnedRequestId = 0;
|
||||||
|
_pinnedLoaded = true;
|
||||||
|
applyReceivedSublists(result, true);
|
||||||
_chatsListChanges.fire({});
|
_chatsListChanges.fire({});
|
||||||
}).fail([=](const MTP::Error &error) {
|
}).fail([=](const MTP::Error &error) {
|
||||||
if (error.type() == u"SAVED_DIALOGS_UNSUPPORTED"_q) {
|
if (error.type() == u"SAVED_DIALOGS_UNSUPPORTED"_q) {
|
||||||
@ -186,11 +306,11 @@ void SavedMessages::loadPinned() {
|
|||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavedMessages::apply(
|
SavedMessages::ApplyResult SavedMessages::applyReceivedSublists(
|
||||||
const MTPmessages_SavedDialogs &result,
|
const MTPmessages_SavedDialogs &dialogs,
|
||||||
bool pinned) {
|
bool pinned) {
|
||||||
auto list = (const QVector<MTPSavedDialog>*)nullptr;
|
auto list = (const QVector<MTPSavedDialog>*)nullptr;
|
||||||
result.match([](const MTPDmessages_savedDialogsNotModified &) {
|
dialogs.match([](const MTPDmessages_savedDialogsNotModified &) {
|
||||||
LOG(("API Error: messages.savedDialogsNotModified."));
|
LOG(("API Error: messages.savedDialogsNotModified."));
|
||||||
}, [&](const auto &data) {
|
}, [&](const auto &data) {
|
||||||
_owner->processUsers(data.vusers());
|
_owner->processUsers(data.vusers());
|
||||||
@ -200,22 +320,11 @@ void SavedMessages::apply(
|
|||||||
NewMessageType::Existing);
|
NewMessageType::Existing);
|
||||||
list = &data.vdialogs().v;
|
list = &data.vdialogs().v;
|
||||||
});
|
});
|
||||||
if (pinned) {
|
|
||||||
_pinnedRequestId = 0;
|
|
||||||
_pinnedLoaded = true;
|
|
||||||
} else {
|
|
||||||
_loadMoreRequestId = 0;
|
|
||||||
}
|
|
||||||
if (!list) {
|
if (!list) {
|
||||||
if (!pinned) {
|
return { .allLoaded = true };
|
||||||
_chatsList.setLoaded();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
auto lastValid = false;
|
auto lastValid = false;
|
||||||
auto offsetDate = TimeId();
|
auto result = ApplyResult();
|
||||||
auto offsetId = MsgId();
|
|
||||||
auto offsetPeer = (PeerData*)nullptr;
|
|
||||||
const auto parentPeerId = _parentChat
|
const auto parentPeerId = _parentChat
|
||||||
? _parentChat->id
|
? _parentChat->id
|
||||||
: _owner->session().userPeerId();
|
: _owner->session().userPeerId();
|
||||||
@ -224,9 +333,9 @@ void SavedMessages::apply(
|
|||||||
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
|
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
|
||||||
const auto topId = MsgId(data.vtop_message().v);
|
const auto topId = MsgId(data.vtop_message().v);
|
||||||
if (const auto item = _owner->message(parentPeerId, topId)) {
|
if (const auto item = _owner->message(parentPeerId, topId)) {
|
||||||
offsetPeer = peer;
|
result.offset.peer = peer;
|
||||||
offsetDate = item->date();
|
result.offset.date = item->date();
|
||||||
offsetId = topId;
|
result.offset.id = topId;
|
||||||
lastValid = true;
|
lastValid = true;
|
||||||
const auto entry = sublist(peer);
|
const auto entry = sublist(peer);
|
||||||
const auto entryPinned = pinned || data.is_pinned();
|
const auto entryPinned = pinned || data.is_pinned();
|
||||||
@ -239,9 +348,9 @@ void SavedMessages::apply(
|
|||||||
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
|
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
|
||||||
const auto topId = MsgId(data.vtop_message().v);
|
const auto topId = MsgId(data.vtop_message().v);
|
||||||
if (const auto item = _owner->message(parentPeerId, topId)) {
|
if (const auto item = _owner->message(parentPeerId, topId)) {
|
||||||
offsetPeer = peer;
|
result.offset.peer = peer;
|
||||||
offsetDate = item->date();
|
result.offset.date = item->date();
|
||||||
offsetId = topId;
|
result.offset.id = topId;
|
||||||
lastValid = true;
|
lastValid = true;
|
||||||
sublist(peer)->applyMonoforumDialog(data, item);
|
sublist(peer)->applyMonoforumDialog(data, item);
|
||||||
} else {
|
} else {
|
||||||
@ -252,20 +361,14 @@ void SavedMessages::apply(
|
|||||||
if (pinned) {
|
if (pinned) {
|
||||||
} else if (!lastValid) {
|
} else if (!lastValid) {
|
||||||
LOG(("API Error: Unknown message in the end of a slice."));
|
LOG(("API Error: Unknown message in the end of a slice."));
|
||||||
_chatsList.setLoaded();
|
result.allLoaded = true;
|
||||||
} else if (result.type() == mtpc_messages_savedDialogs) {
|
} else if (dialogs.type() == mtpc_messages_savedDialogs) {
|
||||||
_chatsList.setLoaded();
|
result.allLoaded = true;
|
||||||
} else if ((_offsetDate > 0 && offsetDate > _offsetDate)
|
|
||||||
|| (offsetDate == _offsetDate
|
|
||||||
&& offsetId == _offsetId
|
|
||||||
&& offsetPeer == _offsetPeer)) {
|
|
||||||
LOG(("API Error: Bad order in messages.savedDialogs."));
|
|
||||||
_chatsList.setLoaded();
|
|
||||||
} else {
|
|
||||||
_offsetDate = offsetDate;
|
|
||||||
_offsetId = offsetId;
|
|
||||||
_offsetPeer = offsetPeer;
|
|
||||||
}
|
}
|
||||||
|
if (!_stalePeers.empty()) {
|
||||||
|
requestSomeStale();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavedMessages::sendLoadMoreRequests() {
|
void SavedMessages::sendLoadMoreRequests() {
|
||||||
@ -324,7 +427,7 @@ void SavedMessages::applySublistDeleted(not_null<PeerData*> sublistPeer) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto raw = i->second.get();
|
const auto raw = i->second.get();
|
||||||
//Core::App().notifications().clearFromTopic(raw); // #TODO monoforum
|
Core::App().notifications().clearFromSublist(raw);
|
||||||
owner().removeChatListEntry(raw);
|
owner().removeChatListEntry(raw);
|
||||||
|
|
||||||
if (ranges::contains(_lastSublists, not_null(raw))) {
|
if (ranges::contains(_lastSublists, not_null(raw))) {
|
||||||
@ -342,9 +445,10 @@ void SavedMessages::applySublistDeleted(not_null<PeerData*> sublistPeer) {
|
|||||||
|
|
||||||
const auto history = owningHistory();
|
const auto history = owningHistory();
|
||||||
history->destroyMessagesBySublist(sublistPeer);
|
history->destroyMessagesBySublist(sublistPeer);
|
||||||
//session().storage().unload(Storage::SharedMediaUnloadThread(
|
session().storage().unload(Storage::SharedMediaUnloadThread(
|
||||||
// _history->peer->id,
|
_owningHistory->peer->id,
|
||||||
// rootId));
|
MsgId(),
|
||||||
|
sublistPeer->id));
|
||||||
history->setForwardDraft(MsgId(), sublistPeer->id, {});
|
history->setForwardDraft(MsgId(), sublistPeer->id, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,16 @@ namespace Data {
|
|||||||
class Session;
|
class Session;
|
||||||
class SavedSublist;
|
class SavedSublist;
|
||||||
|
|
||||||
|
struct SavedMessagesOffsets {
|
||||||
|
TimeId date = 0;
|
||||||
|
MsgId id = 0;
|
||||||
|
PeerData *peer = nullptr;
|
||||||
|
|
||||||
|
friend inline constexpr auto operator<=>(
|
||||||
|
SavedMessagesOffsets,
|
||||||
|
SavedMessagesOffsets) = default;
|
||||||
|
};
|
||||||
|
|
||||||
class SavedMessages final {
|
class SavedMessages final {
|
||||||
public:
|
public:
|
||||||
explicit SavedMessages(
|
explicit SavedMessages(
|
||||||
@ -37,6 +47,7 @@ public:
|
|||||||
[[nodiscard]] not_null<Dialogs::MainList*> chatsList();
|
[[nodiscard]] not_null<Dialogs::MainList*> chatsList();
|
||||||
[[nodiscard]] not_null<SavedSublist*> sublist(not_null<PeerData*> peer);
|
[[nodiscard]] not_null<SavedSublist*> sublist(not_null<PeerData*> peer);
|
||||||
[[nodiscard]] SavedSublist *sublistLoaded(not_null<PeerData*> peer);
|
[[nodiscard]] SavedSublist *sublistLoaded(not_null<PeerData*> peer);
|
||||||
|
void requestSublist(not_null<PeerData*> peer, Fn<void()> done = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> chatsListChanges() const;
|
[[nodiscard]] rpl::producer<> chatsListChanges() const;
|
||||||
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
|
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
|
||||||
@ -59,13 +70,31 @@ public:
|
|||||||
[[nodiscard]] auto recentSublists() const
|
[[nodiscard]] auto recentSublists() const
|
||||||
-> const std::vector<not_null<SavedSublist*>> &;
|
-> const std::vector<not_null<SavedSublist*>> &;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
[[nodiscard]] rpl::lifetime &lifetime();
|
[[nodiscard]] rpl::lifetime &lifetime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct SublistRequest {
|
||||||
|
mtpRequestId id = 0;
|
||||||
|
std::vector<Fn<void()>> callbacks;
|
||||||
|
};
|
||||||
|
struct ApplyResult {
|
||||||
|
SavedMessagesOffsets offset;
|
||||||
|
bool allLoaded = false;
|
||||||
|
};
|
||||||
|
|
||||||
void loadPinned();
|
void loadPinned();
|
||||||
void apply(const MTPmessages_SavedDialogs &result, bool pinned);
|
ApplyResult applyReceivedSublists(
|
||||||
|
const MTPmessages_SavedDialogs &result,
|
||||||
|
SavedMessagesOffsets &updateOffsets);
|
||||||
|
ApplyResult applyReceivedSublists(
|
||||||
|
const MTPmessages_SavedDialogs &result,
|
||||||
|
bool pinned = false);
|
||||||
|
|
||||||
void reorderLastSublists();
|
void reorderLastSublists();
|
||||||
|
void requestSomeStale();
|
||||||
|
void finishSublistRequest(not_null<PeerData*> peer);
|
||||||
|
|
||||||
void sendLoadMore();
|
void sendLoadMore();
|
||||||
void sendLoadMoreRequests();
|
void sendLoadMoreRequests();
|
||||||
@ -80,13 +109,14 @@ private:
|
|||||||
base::flat_map<
|
base::flat_map<
|
||||||
not_null<PeerData*>,
|
not_null<PeerData*>,
|
||||||
std::unique_ptr<SavedSublist>> _sublists;
|
std::unique_ptr<SavedSublist>> _sublists;
|
||||||
|
base::flat_map<not_null<PeerData*>, SublistRequest> _sublistRequests;
|
||||||
|
base::flat_set<not_null<PeerData*>> _stalePeers;
|
||||||
|
mtpRequestId _staleRequestId = 0;
|
||||||
|
|
||||||
mtpRequestId _loadMoreRequestId = 0;
|
mtpRequestId _loadMoreRequestId = 0;
|
||||||
mtpRequestId _pinnedRequestId = 0;
|
mtpRequestId _pinnedRequestId = 0;
|
||||||
|
|
||||||
TimeId _offsetDate = 0;
|
SavedMessagesOffsets _offset;
|
||||||
MsgId _offsetId = 0;
|
|
||||||
PeerData *_offsetPeer = nullptr;
|
|
||||||
|
|
||||||
SingleQueuedInvokation _loadMore;
|
SingleQueuedInvokation _loadMore;
|
||||||
bool _loadMoreScheduled = false;
|
bool _loadMoreScheduled = false;
|
||||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_saved_sublist.h"
|
#include "data/data_saved_sublist.h"
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "core/application.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
@ -22,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_unread_things.h"
|
#include "history/history_unread_things.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "window/notifications_manager.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
namespace {
|
namespace {
|
||||||
@ -221,7 +223,7 @@ void SavedSublist::applyItemRemoved(MsgId id) {
|
|||||||
|
|
||||||
void SavedSublist::requestChatListMessage() {
|
void SavedSublist::requestChatListMessage() {
|
||||||
if (!chatListMessageKnown()) {
|
if (!chatListMessageKnown()) {
|
||||||
//forum()->requestTopic(_rootId); // #TODO monoforum
|
parent()->requestSublist(sublistPeer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +650,7 @@ void SavedSublist::readTill(
|
|||||||
_readRequestTimer.callOnce(0);
|
_readRequestTimer.callOnce(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Core::App().notifications().clearIncomingFromSublist(this); // #TODO monoforum
|
Core::App().notifications().clearIncomingFromSublist(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavedSublist::sendReadTillRequest() {
|
void SavedSublist::sendReadTillRequest() {
|
||||||
|
@ -132,6 +132,7 @@ GlobalMediaResult ParseGlobalMediaResult(
|
|||||||
std::optional<SearchRequest> PrepareSearchRequest(
|
std::optional<SearchRequest> PrepareSearchRequest(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
Storage::SharedMediaType type,
|
Storage::SharedMediaType type,
|
||||||
const QString &query,
|
const QString &query,
|
||||||
MsgId messageId,
|
MsgId messageId,
|
||||||
@ -168,11 +169,14 @@ std::optional<SearchRequest> PrepareSearchRequest(
|
|||||||
int64(0x3FFFFFFF)));
|
int64(0x3FFFFFFF)));
|
||||||
using Flag = MTPmessages_Search::Flag;
|
using Flag = MTPmessages_Search::Flag;
|
||||||
return MTPmessages_Search(
|
return MTPmessages_Search(
|
||||||
MTP_flags(topicRootId ? Flag::f_top_msg_id : Flag(0)),
|
MTP_flags((topicRootId ? Flag::f_top_msg_id : Flag(0))
|
||||||
|
| (monoforumPeerId ? Flag::f_saved_peer_id : Flag(0))),
|
||||||
peer->input,
|
peer->input,
|
||||||
MTP_string(query),
|
MTP_string(query),
|
||||||
MTP_inputPeerEmpty(),
|
MTP_inputPeerEmpty(),
|
||||||
MTPInputPeer(), // saved_peer_id
|
(monoforumPeerId
|
||||||
|
? peer->owner().peer(monoforumPeerId)->input
|
||||||
|
: MTPInputPeer()),
|
||||||
MTPVector<MTPReaction>(), // saved_reaction
|
MTPVector<MTPReaction>(), // saved_reaction
|
||||||
MTP_int(topicRootId),
|
MTP_int(topicRootId),
|
||||||
filter,
|
filter,
|
||||||
@ -369,12 +373,14 @@ rpl::producer<SparseIdsMergedSlice> SearchController::idsSlice(
|
|||||||
auto createSimpleViewer = [=](
|
auto createSimpleViewer = [=](
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SparseIdsSlice::Key simpleKey,
|
SparseIdsSlice::Key simpleKey,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter) {
|
int limitAfter) {
|
||||||
return simpleIdsSlice(
|
return simpleIdsSlice(
|
||||||
peerId,
|
peerId,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
simpleKey,
|
simpleKey,
|
||||||
query,
|
query,
|
||||||
limitBefore,
|
limitBefore,
|
||||||
@ -384,6 +390,7 @@ rpl::producer<SparseIdsMergedSlice> SearchController::idsSlice(
|
|||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
query.peerId,
|
query.peerId,
|
||||||
query.topicRootId,
|
query.topicRootId,
|
||||||
|
query.monoforumPeerId,
|
||||||
query.migratedPeerId,
|
query.migratedPeerId,
|
||||||
aroundId),
|
aroundId),
|
||||||
limitBefore,
|
limitBefore,
|
||||||
@ -394,6 +401,7 @@ rpl::producer<SparseIdsMergedSlice> SearchController::idsSlice(
|
|||||||
rpl::producer<SparseIdsSlice> SearchController::simpleIdsSlice(
|
rpl::producer<SparseIdsSlice> SearchController::simpleIdsSlice(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
MsgId aroundId,
|
MsgId aroundId,
|
||||||
const Query &query,
|
const Query &query,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
@ -402,8 +410,12 @@ rpl::producer<SparseIdsSlice> SearchController::simpleIdsSlice(
|
|||||||
Expects(IsServerMsgId(aroundId) || (aroundId == 0));
|
Expects(IsServerMsgId(aroundId) || (aroundId == 0));
|
||||||
Expects((aroundId != 0)
|
Expects((aroundId != 0)
|
||||||
|| (limitBefore == 0 && limitAfter == 0));
|
|| (limitBefore == 0 && limitAfter == 0));
|
||||||
Expects((query.peerId == peerId && query.topicRootId == topicRootId)
|
Expects((query.peerId == peerId
|
||||||
|| (query.migratedPeerId == peerId && MsgId(0) == topicRootId));
|
&& query.topicRootId == topicRootId
|
||||||
|
&& query.monoforumPeerId == monoforumPeerId)
|
||||||
|
|| (query.migratedPeerId == peerId
|
||||||
|
&& MsgId(0) == topicRootId
|
||||||
|
&& PeerId(0) == monoforumPeerId));
|
||||||
|
|
||||||
auto it = _cache.find(query);
|
auto it = _cache.find(query);
|
||||||
if (it == _cache.end()) {
|
if (it == _cache.end()) {
|
||||||
@ -437,7 +449,9 @@ rpl::producer<SparseIdsSlice> SearchController::simpleIdsSlice(
|
|||||||
_session->data().itemRemoved(
|
_session->data().itemRemoved(
|
||||||
) | rpl::filter([=](not_null<const HistoryItem*> item) {
|
) | rpl::filter([=](not_null<const HistoryItem*> item) {
|
||||||
return (item->history()->peer->id == peerId)
|
return (item->history()->peer->id == peerId)
|
||||||
&& (!topicRootId || item->topicRootId() == topicRootId);
|
&& (!topicRootId || item->topicRootId() == topicRootId)
|
||||||
|
&& (!monoforumPeerId
|
||||||
|
|| item->sublistPeerId() == monoforumPeerId);
|
||||||
}) | rpl::filter([=](not_null<const HistoryItem*> item) {
|
}) | rpl::filter([=](not_null<const HistoryItem*> item) {
|
||||||
return builder->removeOne(item->id);
|
return builder->removeOne(item->id);
|
||||||
}) | rpl::start_with_next(pushNextSnapshot, lifetime);
|
}) | rpl::start_with_next(pushNextSnapshot, lifetime);
|
||||||
@ -510,6 +524,7 @@ void SearchController::requestMore(
|
|||||||
auto prepared = PrepareSearchRequest(
|
auto prepared = PrepareSearchRequest(
|
||||||
listData->peer,
|
listData->peer,
|
||||||
query.topicRootId,
|
query.topicRootId,
|
||||||
|
query.monoforumPeerId,
|
||||||
query.type,
|
query.type,
|
||||||
query.query,
|
query.query,
|
||||||
key.aroundId,
|
key.aroundId,
|
||||||
|
@ -61,6 +61,7 @@ struct GlobalMediaResult {
|
|||||||
[[nodiscard]] std::optional<SearchRequest> PrepareSearchRequest(
|
[[nodiscard]] std::optional<SearchRequest> PrepareSearchRequest(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
Storage::SharedMediaType type,
|
Storage::SharedMediaType type,
|
||||||
const QString &query,
|
const QString &query,
|
||||||
MsgId messageId,
|
MsgId messageId,
|
||||||
@ -92,6 +93,7 @@ public:
|
|||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
PeerId migratedPeerId = 0;
|
PeerId migratedPeerId = 0;
|
||||||
MediaType type = MediaType::kCount;
|
MediaType type = MediaType::kCount;
|
||||||
QString query;
|
QString query;
|
||||||
@ -151,6 +153,7 @@ private:
|
|||||||
rpl::producer<SparseIdsSlice> simpleIdsSlice(
|
rpl::producer<SparseIdsSlice> simpleIdsSlice(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
MsgId aroundId,
|
MsgId aroundId,
|
||||||
const Query &query,
|
const Query &query,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
|
@ -404,6 +404,7 @@ void Session::clear() {
|
|||||||
channel->setFlags(channel->flags()
|
channel->setFlags(channel->flags()
|
||||||
& ~(ChannelDataFlag::Forum | ChannelDataFlag::MonoforumAdmin));
|
& ~(ChannelDataFlag::Forum | ChannelDataFlag::MonoforumAdmin));
|
||||||
}
|
}
|
||||||
|
_savedMessages->clear();
|
||||||
|
|
||||||
_sendActionManager->clear();
|
_sendActionManager->clear();
|
||||||
|
|
||||||
|
@ -110,11 +110,13 @@ rpl::producer<SparseIdsSlice> SharedMediaViewer(
|
|||||||
auto requestMediaAround = [
|
auto requestMediaAround = [
|
||||||
peer = session->data().peer(key.peerId),
|
peer = session->data().peer(key.peerId),
|
||||||
topicRootId = key.topicRootId,
|
topicRootId = key.topicRootId,
|
||||||
|
monoforumPeerId = key.monoforumPeerId,
|
||||||
type = key.type
|
type = key.type
|
||||||
](const SparseIdsSliceBuilder::AroundData &data) {
|
](const SparseIdsSliceBuilder::AroundData &data) {
|
||||||
peer->session().api().requestSharedMedia(
|
peer->session().api().requestSharedMedia(
|
||||||
peer,
|
peer,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
type,
|
type,
|
||||||
data.aroundId,
|
data.aroundId,
|
||||||
data.direction);
|
data.direction);
|
||||||
@ -131,6 +133,7 @@ rpl::producer<SparseIdsSlice> SharedMediaViewer(
|
|||||||
) | rpl::filter([=](const SliceUpdate &update) {
|
) | rpl::filter([=](const SliceUpdate &update) {
|
||||||
return (update.peerId == key.peerId)
|
return (update.peerId == key.peerId)
|
||||||
&& (update.topicRootId == key.topicRootId)
|
&& (update.topicRootId == key.topicRootId)
|
||||||
|
&& (update.monoforumPeerId == key.monoforumPeerId)
|
||||||
&& (update.type == key.type);
|
&& (update.type == key.type);
|
||||||
}) | rpl::filter([=](const SliceUpdate &update) {
|
}) | rpl::filter([=](const SliceUpdate &update) {
|
||||||
return builder->applyUpdate(update.data);
|
return builder->applyUpdate(update.data);
|
||||||
@ -151,6 +154,8 @@ rpl::producer<SparseIdsSlice> SharedMediaViewer(
|
|||||||
return (update.peerId == key.peerId)
|
return (update.peerId == key.peerId)
|
||||||
&& (!update.topicRootId
|
&& (!update.topicRootId
|
||||||
|| update.topicRootId == key.topicRootId)
|
|| update.topicRootId == key.topicRootId)
|
||||||
|
&& (!update.monoforumPeerId
|
||||||
|
|| update.monoforumPeerId == key.monoforumPeerId)
|
||||||
&& update.types.test(key.type);
|
&& update.types.test(key.type);
|
||||||
}) | rpl::filter([=] {
|
}) | rpl::filter([=] {
|
||||||
return builder->removeAll();
|
return builder->removeAll();
|
||||||
@ -236,6 +241,7 @@ rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
|
|||||||
auto createSimpleViewer = [=](
|
auto createSimpleViewer = [=](
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SparseIdsSlice::Key simpleKey,
|
SparseIdsSlice::Key simpleKey,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter) {
|
int limitAfter) {
|
||||||
@ -244,6 +250,7 @@ rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
|
|||||||
Storage::SharedMediaKey(
|
Storage::SharedMediaKey(
|
||||||
peerId,
|
peerId,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
key.type,
|
key.type,
|
||||||
simpleKey),
|
simpleKey),
|
||||||
limitBefore,
|
limitBefore,
|
||||||
|
@ -74,11 +74,13 @@ public:
|
|||||||
Key(
|
Key(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Type type,
|
Type type,
|
||||||
UniversalMsgId universalId)
|
UniversalMsgId universalId)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
, migratedPeerId(migratedPeerId)
|
, migratedPeerId(migratedPeerId)
|
||||||
, type(type)
|
, type(type)
|
||||||
, universalId(universalId) {
|
, universalId(universalId) {
|
||||||
@ -91,6 +93,7 @@ public:
|
|||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
PeerId migratedPeerId = 0;
|
PeerId migratedPeerId = 0;
|
||||||
Type type = Type::kCount;
|
Type type = Type::kCount;
|
||||||
UniversalMsgId universalId;
|
UniversalMsgId universalId;
|
||||||
@ -120,6 +123,7 @@ public:
|
|||||||
return {
|
return {
|
||||||
key.peerId,
|
key.peerId,
|
||||||
key.topicRootId,
|
key.topicRootId,
|
||||||
|
key.monoforumPeerId,
|
||||||
key.migratedPeerId,
|
key.migratedPeerId,
|
||||||
v::is<MessageId>(key.universalId)
|
v::is<MessageId>(key.universalId)
|
||||||
? v::get<MessageId>(key.universalId)
|
? v::get<MessageId>(key.universalId)
|
||||||
@ -130,6 +134,7 @@ public:
|
|||||||
return {
|
return {
|
||||||
key.peerId,
|
key.peerId,
|
||||||
key.topicRootId,
|
key.topicRootId,
|
||||||
|
key.monoforumPeerId,
|
||||||
key.migratedPeerId,
|
key.migratedPeerId,
|
||||||
ServerMaxMsgId - 1
|
ServerMaxMsgId - 1
|
||||||
};
|
};
|
||||||
|
@ -377,7 +377,10 @@ rpl::producer<SparseIdsMergedSlice> SparseIdsMergedSlice::CreateViewer(
|
|||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter,
|
int limitAfter,
|
||||||
Fn<SimpleViewerFunction> simpleViewer) {
|
Fn<SimpleViewerFunction> simpleViewer) {
|
||||||
Expects(!key.topicRootId || !key.migratedPeerId);
|
Expects(!key.topicRootId
|
||||||
|
|| (!key.monoforumPeerId && !key.migratedPeerId));
|
||||||
|
Expects(!key.monoforumPeerId
|
||||||
|
|| (!key.topicRootId && !key.migratedPeerId));
|
||||||
Expects(IsServerMsgId(key.universalId)
|
Expects(IsServerMsgId(key.universalId)
|
||||||
|| (key.universalId == 0)
|
|| (key.universalId == 0)
|
||||||
|| (IsServerMsgId(ServerMaxMsgId + key.universalId) && key.migratedPeerId != 0));
|
|| (IsServerMsgId(ServerMaxMsgId + key.universalId) && key.migratedPeerId != 0));
|
||||||
@ -388,6 +391,7 @@ rpl::producer<SparseIdsMergedSlice> SparseIdsMergedSlice::CreateViewer(
|
|||||||
auto partViewer = simpleViewer(
|
auto partViewer = simpleViewer(
|
||||||
key.peerId,
|
key.peerId,
|
||||||
key.topicRootId,
|
key.topicRootId,
|
||||||
|
key.monoforumPeerId,
|
||||||
SparseIdsMergedSlice::PartKey(key),
|
SparseIdsMergedSlice::PartKey(key),
|
||||||
limitBefore,
|
limitBefore,
|
||||||
limitAfter
|
limitAfter
|
||||||
@ -405,6 +409,7 @@ rpl::producer<SparseIdsMergedSlice> SparseIdsMergedSlice::CreateViewer(
|
|||||||
auto migratedViewer = simpleViewer(
|
auto migratedViewer = simpleViewer(
|
||||||
key.migratedPeerId,
|
key.migratedPeerId,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
SparseIdsMergedSlice::MigratedKey(key),
|
SparseIdsMergedSlice::MigratedKey(key),
|
||||||
limitBefore,
|
limitBefore,
|
||||||
limitAfter);
|
limitAfter);
|
||||||
|
@ -33,11 +33,13 @@ public:
|
|||||||
Key(
|
Key(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
UniversalMsgId universalId)
|
UniversalMsgId universalId)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
, migratedPeerId(topicRootId ? 0 : migratedPeerId)
|
, monoforumPeerId(monoforumPeerId)
|
||||||
|
, migratedPeerId((topicRootId || monoforumPeerId) ? 0 : migratedPeerId)
|
||||||
, universalId(universalId) {
|
, universalId(universalId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ public:
|
|||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
PeerId migratedPeerId = 0;
|
PeerId migratedPeerId = 0;
|
||||||
UniversalMsgId universalId = 0;
|
UniversalMsgId universalId = 0;
|
||||||
};
|
};
|
||||||
@ -72,6 +75,7 @@ public:
|
|||||||
using SimpleViewerFunction = rpl::producer<SparseIdsSlice>(
|
using SimpleViewerFunction = rpl::producer<SparseIdsSlice>(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SparseIdsSlice::Key simpleKey,
|
SparseIdsSlice::Key simpleKey,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter);
|
int limitAfter);
|
||||||
|
@ -1909,7 +1909,7 @@ RowDescriptor InnerWidget::computeChatPreviewRow() const {
|
|||||||
auto result = computeChosenRow();
|
auto result = computeChosenRow();
|
||||||
if (const auto peer = result.key.peer()) {
|
if (const auto peer = result.key.peer()) {
|
||||||
const auto topicId = _pressedTopicJump
|
const auto topicId = _pressedTopicJump
|
||||||
? _pressedTopicJumpRootId
|
? _pressedTopicJumpRootId // #TODO monoforums
|
||||||
: 0;
|
: 0;
|
||||||
if (const auto topic = peer->forumTopicFor(topicId)) {
|
if (const auto topic = peer->forumTopicFor(topicId)) {
|
||||||
return { topic, FullMsgId() };
|
return { topic, FullMsgId() };
|
||||||
|
@ -651,8 +651,38 @@ void History::destroyMessagesBySublist(not_null<PeerData*> sublistPeer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::unpinMessagesFor(MsgId topicRootId) {
|
void History::unpinMessagesFor(MsgId topicRootId, PeerId monoforumPeerId) {
|
||||||
if (!topicRootId) {
|
if (topicRootId) {
|
||||||
|
session().storage().remove(
|
||||||
|
Storage::SharedMediaRemoveAll(
|
||||||
|
peer->id,
|
||||||
|
topicRootId,
|
||||||
|
Storage::SharedMediaType::Pinned));
|
||||||
|
if (const auto topic = peer->forumTopicFor(topicRootId)) {
|
||||||
|
topic->setHasPinnedMessages(false);
|
||||||
|
}
|
||||||
|
for (const auto &item : _items) {
|
||||||
|
if (item->isPinned() && item->topicRootId() == topicRootId) {
|
||||||
|
item->setIsPinned(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (monoforumPeerId) {
|
||||||
|
session().storage().remove(
|
||||||
|
Storage::SharedMediaRemoveAll(
|
||||||
|
peer->id,
|
||||||
|
monoforumPeerId,
|
||||||
|
Storage::SharedMediaType::Pinned));
|
||||||
|
if (const auto sublist = peer->monoforumSublistFor(
|
||||||
|
monoforumPeerId)) {
|
||||||
|
sublist->setHasPinnedMessages(false);
|
||||||
|
}
|
||||||
|
for (const auto &item : _items) {
|
||||||
|
if (item->isPinned()
|
||||||
|
&& item->sublistPeerId() == monoforumPeerId) {
|
||||||
|
item->setIsPinned(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
session().storage().remove(
|
session().storage().remove(
|
||||||
Storage::SharedMediaRemoveAll(
|
Storage::SharedMediaRemoveAll(
|
||||||
peer->id,
|
peer->id,
|
||||||
@ -668,20 +698,6 @@ void History::unpinMessagesFor(MsgId topicRootId) {
|
|||||||
item->setIsPinned(false);
|
item->setIsPinned(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
session().storage().remove(
|
|
||||||
Storage::SharedMediaRemoveAll(
|
|
||||||
peer->id,
|
|
||||||
topicRootId,
|
|
||||||
Storage::SharedMediaType::Pinned));
|
|
||||||
if (const auto topic = peer->forumTopicFor(topicRootId)) {
|
|
||||||
topic->setHasPinnedMessages(false);
|
|
||||||
}
|
|
||||||
for (const auto &item : _items) {
|
|
||||||
if (item->isPinned() && item->topicRootId() == topicRootId) {
|
|
||||||
item->setIsPinned(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,6 +914,7 @@ not_null<HistoryItem*> History::addNewToBack(
|
|||||||
storage.add(Storage::SharedMediaAddExisting(
|
storage.add(Storage::SharedMediaAddExisting(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
types,
|
types,
|
||||||
item->id,
|
item->id,
|
||||||
{ from, till }));
|
{ from, till }));
|
||||||
@ -909,6 +926,7 @@ not_null<HistoryItem*> History::addNewToBack(
|
|||||||
storage.add(Storage::SharedMediaAddExisting(
|
storage.add(Storage::SharedMediaAddExisting(
|
||||||
peer->id,
|
peer->id,
|
||||||
topic->rootId(),
|
topic->rootId(),
|
||||||
|
PeerId(), // monoforumPeerId
|
||||||
types,
|
types,
|
||||||
item->id,
|
item->id,
|
||||||
{ item->id, item->id}));
|
{ item->id, item->id}));
|
||||||
@ -916,6 +934,18 @@ not_null<HistoryItem*> History::addNewToBack(
|
|||||||
topic->setHasPinnedMessages(true);
|
topic->setHasPinnedMessages(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (const auto sublist = item->savedSublist()) {
|
||||||
|
storage.add(Storage::SharedMediaAddExisting(
|
||||||
|
peer->id,
|
||||||
|
MsgId(), // topicRootId
|
||||||
|
item->sublistPeerId(),
|
||||||
|
types,
|
||||||
|
item->id,
|
||||||
|
{ item->id, item->id }));
|
||||||
|
if (pinned) {
|
||||||
|
sublist->setHasPinnedMessages(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item->from()->id) {
|
if (item->from()->id) {
|
||||||
@ -1182,7 +1212,8 @@ void History::applyServiceChanges(
|
|||||||
if (id && item) {
|
if (id && item) {
|
||||||
session().storage().add(Storage::SharedMediaAddSlice(
|
session().storage().add(Storage::SharedMediaAddSlice(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0),
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
{ id },
|
{ id },
|
||||||
{ id, ServerMaxMsgId }));
|
{ id, ServerMaxMsgId }));
|
||||||
@ -1191,11 +1222,22 @@ void History::applyServiceChanges(
|
|||||||
session().storage().add(Storage::SharedMediaAddSlice(
|
session().storage().add(Storage::SharedMediaAddSlice(
|
||||||
peer->id,
|
peer->id,
|
||||||
topic->rootId(),
|
topic->rootId(),
|
||||||
|
PeerId(), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
{ id },
|
{ id },
|
||||||
{ id, ServerMaxMsgId }));
|
{ id, ServerMaxMsgId }));
|
||||||
topic->setHasPinnedMessages(true);
|
topic->setHasPinnedMessages(true);
|
||||||
}
|
}
|
||||||
|
if (const auto sublist = item->savedSublist()) {
|
||||||
|
session().storage().add(Storage::SharedMediaAddSlice(
|
||||||
|
peer->id,
|
||||||
|
MsgId(), // topicRootId
|
||||||
|
item->sublistPeerId(),
|
||||||
|
Storage::SharedMediaType::Pinned,
|
||||||
|
{ id },
|
||||||
|
{ id, ServerMaxMsgId }));
|
||||||
|
sublist->setHasPinnedMessages(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
||||||
LOG(("API Error: story reply in messageActionPinMessage."));
|
LOG(("API Error: story reply in messageActionPinMessage."));
|
||||||
@ -1470,6 +1512,7 @@ void History::addEdgesToSharedMedia() {
|
|||||||
session().storage().add(Storage::SharedMediaAddSlice(
|
session().storage().add(Storage::SharedMediaAddSlice(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
type,
|
type,
|
||||||
{},
|
{},
|
||||||
{ from, till }));
|
{ from, till }));
|
||||||
@ -1683,6 +1726,7 @@ void History::addToSharedMedia(
|
|||||||
session().storage().add(Storage::SharedMediaAddSlice(
|
session().storage().add(Storage::SharedMediaAddSlice(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
type,
|
type,
|
||||||
std::move(medias[i]),
|
std::move(medias[i]),
|
||||||
{ from, till }));
|
{ from, till }));
|
||||||
@ -3162,11 +3206,9 @@ void History::forceFullResize() {
|
|||||||
Data::Thread *History::threadFor(MsgId topicRootId, PeerId monoforumPeerId) {
|
Data::Thread *History::threadFor(MsgId topicRootId, PeerId monoforumPeerId) {
|
||||||
return topicRootId
|
return topicRootId
|
||||||
? peer->forumTopicFor(topicRootId)
|
? peer->forumTopicFor(topicRootId)
|
||||||
: !monoforumPeerId
|
: monoforumPeerId
|
||||||
? static_cast<Data::Thread*>(this)
|
? peer->monoforumSublistFor(monoforumPeerId)
|
||||||
: peer->monoforum()
|
: static_cast<Data::Thread*>(this);
|
||||||
? peer->monoforum()->sublistLoaded(owner().peer(monoforumPeerId))
|
|
||||||
: nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Data::Thread *History::threadFor(
|
const Data::Thread *History::threadFor(
|
||||||
|
@ -141,7 +141,7 @@ public:
|
|||||||
void destroyMessagesByTopic(MsgId topicRootId);
|
void destroyMessagesByTopic(MsgId topicRootId);
|
||||||
void destroyMessagesBySublist(not_null<PeerData*> sublistPeer);
|
void destroyMessagesBySublist(not_null<PeerData*> sublistPeer);
|
||||||
|
|
||||||
void unpinMessagesFor(MsgId topicRootId);
|
void unpinMessagesFor(MsgId topicRootId, PeerId monoforumPeerId);
|
||||||
|
|
||||||
not_null<HistoryItem*> addNewMessage(
|
not_null<HistoryItem*> addNewMessage(
|
||||||
MsgId id,
|
MsgId id,
|
||||||
|
@ -1513,6 +1513,7 @@ void HistoryItem::setIsPinned(bool pinned) {
|
|||||||
storage.add(Storage::SharedMediaAddExisting(
|
storage.add(Storage::SharedMediaAddExisting(
|
||||||
_history->peer->id,
|
_history->peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
id,
|
id,
|
||||||
{ id, id }));
|
{ id, id }));
|
||||||
@ -1521,11 +1522,22 @@ void HistoryItem::setIsPinned(bool pinned) {
|
|||||||
storage.add(Storage::SharedMediaAddExisting(
|
storage.add(Storage::SharedMediaAddExisting(
|
||||||
_history->peer->id,
|
_history->peer->id,
|
||||||
topic->rootId(),
|
topic->rootId(),
|
||||||
|
PeerId(), // monoforumPeerId
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
id,
|
id,
|
||||||
{ id, id }));
|
{ id, id }));
|
||||||
topic->setHasPinnedMessages(true);
|
topic->setHasPinnedMessages(true);
|
||||||
}
|
}
|
||||||
|
if (const auto sublist = this->savedSublist()) {
|
||||||
|
storage.add(Storage::SharedMediaAddExisting(
|
||||||
|
_history->peer->id,
|
||||||
|
MsgId(0), // topicRootId
|
||||||
|
sublistPeerId(),
|
||||||
|
Storage::SharedMediaType::Pinned,
|
||||||
|
id,
|
||||||
|
{ id, id }));
|
||||||
|
sublist->setHasPinnedMessages(true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_flags &= ~MessageFlag::Pinned;
|
_flags &= ~MessageFlag::Pinned;
|
||||||
if (_flags & MessageFlag::StoryItem) {
|
if (_flags & MessageFlag::StoryItem) {
|
||||||
@ -2238,6 +2250,7 @@ void HistoryItem::addToSharedMediaIndex() {
|
|||||||
_history->session().storage().add(Storage::SharedMediaAddNew(
|
_history->session().storage().add(Storage::SharedMediaAddNew(
|
||||||
_history->peer->id,
|
_history->peer->id,
|
||||||
topicRootId(),
|
topicRootId(),
|
||||||
|
sublistPeerId(),
|
||||||
types,
|
types,
|
||||||
id));
|
id));
|
||||||
if (types.test(Storage::SharedMediaType::Pinned)) {
|
if (types.test(Storage::SharedMediaType::Pinned)) {
|
||||||
@ -2245,6 +2258,9 @@ void HistoryItem::addToSharedMediaIndex() {
|
|||||||
if (const auto topic = this->topic()) {
|
if (const auto topic = this->topic()) {
|
||||||
topic->setHasPinnedMessages(true);
|
topic->setHasPinnedMessages(true);
|
||||||
}
|
}
|
||||||
|
if (const auto sublist = this->savedSublist()) {
|
||||||
|
sublist->setHasPinnedMessages(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6038,7 +6038,7 @@ bool HistoryWidget::showSendingFilesError(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MsgId HistoryWidget::resolveReplyToTopicRootId() {
|
MsgId HistoryWidget::resolveReplyToTopicRootId() { // #TODO monoforums
|
||||||
Expects(_peer != nullptr);
|
Expects(_peer != nullptr);
|
||||||
|
|
||||||
const auto replyToInfo = replyTo();
|
const auto replyToInfo = replyTo();
|
||||||
@ -7601,6 +7601,7 @@ void HistoryWidget::updatePinnedViewer() {
|
|||||||
_minPinnedId = Data::ResolveMinPinnedId(
|
_minPinnedId = Data::ResolveMinPinnedId(
|
||||||
_peer,
|
_peer,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
_migrated ? _migrated->peer.get() : nullptr);
|
_migrated ? _migrated->peer.get() : nullptr);
|
||||||
}
|
}
|
||||||
if (_pinnedClickedId
|
if (_pinnedClickedId
|
||||||
@ -7680,6 +7681,7 @@ void HistoryWidget::checkPinnedBarState() {
|
|||||||
const auto currentPinnedId = Data::ResolveTopPinnedId(
|
const auto currentPinnedId = Data::ResolveTopPinnedId(
|
||||||
_peer,
|
_peer,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
_migrated ? _migrated->peer.get() : nullptr);
|
_migrated ? _migrated->peer.get() : nullptr);
|
||||||
const auto universalPinnedId = !currentPinnedId
|
const auto universalPinnedId = !currentPinnedId
|
||||||
? int32(0)
|
? int32(0)
|
||||||
@ -7713,6 +7715,7 @@ void HistoryWidget::checkPinnedBarState() {
|
|||||||
auto pinnedRefreshed = Info::Profile::SharedMediaCountValue(
|
auto pinnedRefreshed = Info::Profile::SharedMediaCountValue(
|
||||||
_peer,
|
_peer,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
nullptr,
|
nullptr,
|
||||||
Storage::SharedMediaType::Pinned
|
Storage::SharedMediaType::Pinned
|
||||||
) | rpl::distinct_until_changed(
|
) | rpl::distinct_until_changed(
|
||||||
@ -8593,6 +8596,7 @@ void HistoryWidget::hidePinnedMessage() {
|
|||||||
controller(),
|
controller(),
|
||||||
_peer,
|
_peer,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
crl::guard(this, callback));
|
crl::guard(this, callback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ void ChatMemento::setFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Data::ForumTopic *ChatMemento::topicForRemoveRequests() const {
|
Data::ForumTopic *ChatMemento::topicForRemoveRequests() const {// #TODO monoforums
|
||||||
return _id.repliesRootId
|
return _id.repliesRootId
|
||||||
? _id.history->peer->forumTopicFor(_id.repliesRootId)
|
? _id.history->peer->forumTopicFor(_id.repliesRootId)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
@ -233,6 +233,9 @@ ChatWidget::ChatWidget(
|
|||||||
, _topic(lookupTopic())
|
, _topic(lookupTopic())
|
||||||
, _areComments(computeAreComments())
|
, _areComments(computeAreComments())
|
||||||
, _sublist(_id.sublist)
|
, _sublist(_id.sublist)
|
||||||
|
, _monoforumPeerId((_sublist && _sublist->parentChat())
|
||||||
|
? _sublist->sublistPeer()->id
|
||||||
|
: PeerId())
|
||||||
, _sendAction(_repliesRootId
|
, _sendAction(_repliesRootId
|
||||||
? _history->owner().sendActionManager().repliesPainter(
|
? _history->owner().sendActionManager().repliesPainter(
|
||||||
_history,
|
_history,
|
||||||
@ -772,7 +775,7 @@ void ChatWidget::setupComposeControls() {
|
|||||||
_composeControls->setHistory({
|
_composeControls->setHistory({
|
||||||
.history = _history.get(),
|
.history = _history.get(),
|
||||||
.topicRootId = _topic ? _topic->rootId() : MsgId(),
|
.topicRootId = _topic ? _topic->rootId() : MsgId(),
|
||||||
.monoforumPeerId = _sublist ? _sublist->sublistPeer()->id : PeerId(),
|
.monoforumPeerId = _monoforumPeerId,
|
||||||
.showSlowmodeError = [=] { return showSlowmodeError(); },
|
.showSlowmodeError = [=] { return showSlowmodeError(); },
|
||||||
.sendActionFactory = [=] { return prepareSendAction({}); },
|
.sendActionFactory = [=] { return prepareSendAction({}); },
|
||||||
.slowmodeSecondsLeft = SlowmodeSecondsLeft(_peer),
|
.slowmodeSecondsLeft = SlowmodeSecondsLeft(_peer),
|
||||||
@ -1781,20 +1784,17 @@ SendMenu::Details ChatWidget::sendMenuDetails() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FullReplyTo ChatWidget::replyTo() const {
|
FullReplyTo ChatWidget::replyTo() const {
|
||||||
const auto monoforumPeerId = (_sublist && _sublist->parentChat())
|
|
||||||
? _sublist->sublistPeer()->id
|
|
||||||
: PeerId();
|
|
||||||
if (auto custom = _composeControls->replyingToMessage()) {
|
if (auto custom = _composeControls->replyingToMessage()) {
|
||||||
const auto item = custom.messageId
|
const auto item = custom.messageId
|
||||||
? session().data().message(custom.messageId)
|
? session().data().message(custom.messageId)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto sublistPeerId = item ? item->sublistPeerId() : PeerId();
|
const auto sublistPeerId = item ? item->sublistPeerId() : PeerId();
|
||||||
if (!item
|
if (!item
|
||||||
|| !monoforumPeerId
|
|| !_monoforumPeerId
|
||||||
|| (sublistPeerId == monoforumPeerId)) {
|
|| (sublistPeerId == _monoforumPeerId)) {
|
||||||
// Never answer to a message in a wrong monoforum peer id.
|
// Never answer to a message in a wrong monoforum peer id.
|
||||||
custom.topicRootId = _repliesRootId;
|
custom.topicRootId = _repliesRootId;
|
||||||
custom.monoforumPeerId = monoforumPeerId;
|
custom.monoforumPeerId = _monoforumPeerId;
|
||||||
return custom;
|
return custom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1803,7 +1803,7 @@ FullReplyTo ChatWidget::replyTo() const {
|
|||||||
? FullMsgId(_peer->id, _repliesRootId)
|
? FullMsgId(_peer->id, _repliesRootId)
|
||||||
: FullMsgId()),
|
: FullMsgId()),
|
||||||
.topicRootId = _repliesRootId,
|
.topicRootId = _repliesRootId,
|
||||||
.monoforumPeerId = monoforumPeerId,
|
.monoforumPeerId = _monoforumPeerId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1850,7 +1850,10 @@ void ChatWidget::updatePinnedViewer() {
|
|||||||
_pinnedClickedId = FullMsgId();
|
_pinnedClickedId = FullMsgId();
|
||||||
}
|
}
|
||||||
if (_pinnedClickedId && !_minPinnedId) {
|
if (_pinnedClickedId && !_minPinnedId) {
|
||||||
_minPinnedId = Data::ResolveMinPinnedId(_peer, _repliesRootId);
|
_minPinnedId = Data::ResolveMinPinnedId(
|
||||||
|
_peer,
|
||||||
|
_repliesRootId,
|
||||||
|
_monoforumPeerId);
|
||||||
}
|
}
|
||||||
if (_pinnedClickedId && _minPinnedId && _minPinnedId >= _pinnedClickedId) {
|
if (_pinnedClickedId && _minPinnedId && _minPinnedId >= _pinnedClickedId) {
|
||||||
// After click on the last pinned message we should the top one.
|
// After click on the last pinned message we should the top one.
|
||||||
@ -1955,6 +1958,7 @@ void ChatWidget::setupPinnedTracker() {
|
|||||||
Storage::SharedMediaKey(
|
Storage::SharedMediaKey(
|
||||||
_topic->channel()->id,
|
_topic->channel()->id,
|
||||||
_repliesRootId,
|
_repliesRootId,
|
||||||
|
_monoforumPeerId,
|
||||||
Storage::SharedMediaType::Pinned,
|
Storage::SharedMediaType::Pinned,
|
||||||
ServerMaxMsgId - 1),
|
ServerMaxMsgId - 1),
|
||||||
1,
|
1,
|
||||||
@ -1968,10 +1972,15 @@ void ChatWidget::setupPinnedTracker() {
|
|||||||
const auto peerId = _peer->id;
|
const auto peerId = _peer->id;
|
||||||
const auto hiddenId = settings.hiddenPinnedMessageId(
|
const auto hiddenId = settings.hiddenPinnedMessageId(
|
||||||
peerId,
|
peerId,
|
||||||
_repliesRootId);
|
_repliesRootId,
|
||||||
|
_monoforumPeerId);
|
||||||
const auto last = result.size() ? result[result.size() - 1] : 0;
|
const auto last = result.size() ? result[result.size() - 1] : 0;
|
||||||
if (hiddenId && hiddenId != last) {
|
if (hiddenId && hiddenId != last) {
|
||||||
settings.setHiddenPinnedMessageId(peerId, _repliesRootId, 0);
|
settings.setHiddenPinnedMessageId(
|
||||||
|
peerId,
|
||||||
|
_repliesRootId,
|
||||||
|
_monoforumPeerId,
|
||||||
|
0);
|
||||||
_history->session().saveSettingsDelayed();
|
_history->session().saveSettingsDelayed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1987,10 +1996,12 @@ void ChatWidget::checkPinnedBarState() {
|
|||||||
? MsgId(0)
|
? MsgId(0)
|
||||||
: _peer->session().settings().hiddenPinnedMessageId(
|
: _peer->session().settings().hiddenPinnedMessageId(
|
||||||
_peer->id,
|
_peer->id,
|
||||||
_repliesRootId);
|
_repliesRootId,
|
||||||
|
_monoforumPeerId);
|
||||||
const auto currentPinnedId = Data::ResolveTopPinnedId(
|
const auto currentPinnedId = Data::ResolveTopPinnedId(
|
||||||
_peer,
|
_peer,
|
||||||
_repliesRootId);
|
_repliesRootId,
|
||||||
|
_monoforumPeerId);
|
||||||
const auto universalPinnedId = !currentPinnedId
|
const auto universalPinnedId = !currentPinnedId
|
||||||
? MsgId(0)
|
? MsgId(0)
|
||||||
: currentPinnedId.msg;
|
: currentPinnedId.msg;
|
||||||
@ -2021,6 +2032,7 @@ void ChatWidget::checkPinnedBarState() {
|
|||||||
auto pinnedRefreshed = Info::Profile::SharedMediaCountValue(
|
auto pinnedRefreshed = Info::Profile::SharedMediaCountValue(
|
||||||
_peer,
|
_peer,
|
||||||
_repliesRootId,
|
_repliesRootId,
|
||||||
|
_monoforumPeerId,
|
||||||
nullptr,
|
nullptr,
|
||||||
Storage::SharedMediaType::Pinned
|
Storage::SharedMediaType::Pinned
|
||||||
) | rpl::distinct_until_changed(
|
) | rpl::distinct_until_changed(
|
||||||
@ -2187,6 +2199,7 @@ void ChatWidget::hidePinnedMessage() {
|
|||||||
controller(),
|
controller(),
|
||||||
_peer,
|
_peer,
|
||||||
_repliesRootId,
|
_repliesRootId,
|
||||||
|
_monoforumPeerId,
|
||||||
crl::guard(this, callback));
|
crl::guard(this, callback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3193,7 +3206,9 @@ void ChatWidget::listShowPremiumToast(not_null<DocumentData*> document) {
|
|||||||
void ChatWidget::listOpenPhoto(
|
void ChatWidget::listOpenPhoto(
|
||||||
not_null<PhotoData*> photo,
|
not_null<PhotoData*> photo,
|
||||||
FullMsgId context) {
|
FullMsgId context) {
|
||||||
controller()->openPhoto(photo, { context, _repliesRootId });
|
controller()->openPhoto(
|
||||||
|
photo,
|
||||||
|
{ context, _repliesRootId, _monoforumPeerId });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWidget::listOpenDocument(
|
void ChatWidget::listOpenDocument(
|
||||||
@ -3203,7 +3218,7 @@ void ChatWidget::listOpenDocument(
|
|||||||
controller()->openDocument(
|
controller()->openDocument(
|
||||||
document,
|
document,
|
||||||
showInMediaView,
|
showInMediaView,
|
||||||
{ context, _repliesRootId });
|
{ context, _repliesRootId, _monoforumPeerId });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWidget::listPaintEmpty(
|
void ChatWidget::listPaintEmpty(
|
||||||
|
@ -394,6 +394,7 @@ private:
|
|||||||
rpl::variable<bool> _areComments = false;
|
rpl::variable<bool> _areComments = false;
|
||||||
|
|
||||||
Data::SavedSublist *_sublist = nullptr;
|
Data::SavedSublist *_sublist = nullptr;
|
||||||
|
PeerId _monoforumPeerId;
|
||||||
|
|
||||||
std::shared_ptr<SendActionPainter> _sendAction;
|
std::shared_ptr<SendActionPainter> _sendAction;
|
||||||
std::shared_ptr<Ui::ChatTheme> _theme;
|
std::shared_ptr<Ui::ChatTheme> _theme;
|
||||||
|
@ -195,6 +195,7 @@ void PinnedWidget::setupClearButton() {
|
|||||||
controller(),
|
controller(),
|
||||||
_history->peer,
|
_history->peer,
|
||||||
_thread->topicRootId(),
|
_thread->topicRootId(),
|
||||||
|
_thread->monoforumPeerId(),
|
||||||
crl::guard(this, callback));
|
crl::guard(this, callback));
|
||||||
} else {
|
} else {
|
||||||
Window::UnpinAllMessages(controller(), _thread);
|
Window::UnpinAllMessages(controller(), _thread);
|
||||||
@ -517,6 +518,7 @@ rpl::producer<Data::MessagesSlice> PinnedWidget::listSource(
|
|||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
_history->peer->id,
|
_history->peer->id,
|
||||||
_thread->topicRootId(),
|
_thread->topicRootId(),
|
||||||
|
_thread->monoforumPeerId(),
|
||||||
_migratedPeer ? _migratedPeer->id : 0,
|
_migratedPeer ? _migratedPeer->id : 0,
|
||||||
messageId),
|
messageId),
|
||||||
Storage::SharedMediaType::Pinned),
|
Storage::SharedMediaType::Pinned),
|
||||||
|
@ -86,6 +86,7 @@ void PinnedTracker::refreshViewer() {
|
|||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
peer->id,
|
peer->id,
|
||||||
_thread->topicRootId(),
|
_thread->topicRootId(),
|
||||||
|
_thread->monoforumPeerId(),
|
||||||
_migratedPeer ? _migratedPeer->id : 0,
|
_migratedPeer ? _migratedPeer->id : 0,
|
||||||
_viewerAroundId),
|
_viewerAroundId),
|
||||||
Storage::SharedMediaType::Pinned),
|
Storage::SharedMediaType::Pinned),
|
||||||
|
@ -751,7 +751,7 @@ void TopBarWidget::infoClicked() {
|
|||||||
_controller->showSection(std::make_shared<Info::Memento>(topic));
|
_controller->showSection(std::make_shared<Info::Memento>(topic));
|
||||||
} else if (const auto sublist = key.sublist()) {
|
} else if (const auto sublist = key.sublist()) {
|
||||||
_controller->showSection(std::make_shared<Info::Memento>(
|
_controller->showSection(std::make_shared<Info::Memento>(
|
||||||
sublist->owningHistory()->peer,
|
sublist,
|
||||||
Info::Section(Storage::SharedMediaType::Photo)));
|
Info::Section(Storage::SharedMediaType::Photo)));
|
||||||
} else if (key.peer()->savedSublistsInfo()) {
|
} else if (key.peer()->savedSublistsInfo()) {
|
||||||
_controller->showSection(std::make_shared<Info::Memento>(
|
_controller->showSection(std::make_shared<Info::Memento>(
|
||||||
|
@ -21,7 +21,7 @@ namespace Info {
|
|||||||
namespace CommonGroups {
|
namespace CommonGroups {
|
||||||
|
|
||||||
Memento::Memento(not_null<UserData*> user)
|
Memento::Memento(not_null<UserData*> user)
|
||||||
: ContentMemento(user, nullptr, PeerId()) {
|
: ContentMemento(user, nullptr, nullptr, PeerId()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
|
@ -307,6 +307,7 @@ QRect ContentWidget::floatPlayerAvailableRect() const {
|
|||||||
void ContentWidget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
void ContentWidget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
||||||
const auto peer = _controller->key().peer();
|
const auto peer = _controller->key().peer();
|
||||||
const auto topic = _controller->key().topic();
|
const auto topic = _controller->key().topic();
|
||||||
|
const auto sublist = _controller->key().sublist();
|
||||||
if (!peer && !topic) {
|
if (!peer && !topic) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -316,6 +317,8 @@ void ContentWidget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
|||||||
Dialogs::EntryState{
|
Dialogs::EntryState{
|
||||||
.key = (topic
|
.key = (topic
|
||||||
? Dialogs::Key{ topic }
|
? Dialogs::Key{ topic }
|
||||||
|
: sublist
|
||||||
|
? Dialogs::Key{ sublist }
|
||||||
: Dialogs::Key{ peer->owner().history(peer) }),
|
: Dialogs::Key{ peer->owner().history(peer) }),
|
||||||
.section = Dialogs::EntryState::Section::Profile,
|
.section = Dialogs::EntryState::Section::Profile,
|
||||||
},
|
},
|
||||||
@ -465,6 +468,8 @@ void ContentWidget::setupSwipeHandler(not_null<Ui::RpWidget*> widget) {
|
|||||||
Key ContentMemento::key() const {
|
Key ContentMemento::key() const {
|
||||||
if (const auto topic = this->topic()) {
|
if (const auto topic = this->topic()) {
|
||||||
return Key(topic);
|
return Key(topic);
|
||||||
|
} else if (const auto sublist = this->sublist()) {
|
||||||
|
return Key(sublist);
|
||||||
} else if (const auto peer = this->peer()) {
|
} else if (const auto peer = this->peer()) {
|
||||||
return Key(peer);
|
return Key(peer);
|
||||||
} else if (const auto poll = this->poll()) {
|
} else if (const auto poll = this->poll()) {
|
||||||
@ -489,12 +494,14 @@ Key ContentMemento::key() const {
|
|||||||
ContentMemento::ContentMemento(
|
ContentMemento::ContentMemento(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Data::ForumTopic *topic,
|
Data::ForumTopic *topic,
|
||||||
|
Data::SavedSublist *sublist,
|
||||||
PeerId migratedPeerId)
|
PeerId migratedPeerId)
|
||||||
: _peer(peer)
|
: _peer(peer)
|
||||||
, _migratedPeerId((!topic && peer->migrateFrom())
|
, _migratedPeerId((!topic && !sublist && peer->migrateFrom())
|
||||||
? peer->migrateFrom()->id
|
? peer->migrateFrom()->id
|
||||||
: 0)
|
: 0)
|
||||||
, _topic(topic) {
|
, _topic(topic)
|
||||||
|
, _sublist(sublist) {
|
||||||
if (_topic) {
|
if (_topic) {
|
||||||
_peer->owner().itemIdChanged(
|
_peer->owner().itemIdChanged(
|
||||||
) | rpl::start_with_next([=](const Data::Session::IdChange &change) {
|
) | rpl::start_with_next([=](const Data::Session::IdChange &change) {
|
||||||
|
@ -210,6 +210,7 @@ public:
|
|||||||
ContentMemento(
|
ContentMemento(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Data::ForumTopic *topic,
|
Data::ForumTopic *topic,
|
||||||
|
Data::SavedSublist *sublist,
|
||||||
PeerId migratedPeerId);
|
PeerId migratedPeerId);
|
||||||
explicit ContentMemento(Settings::Tag settings);
|
explicit ContentMemento(Settings::Tag settings);
|
||||||
explicit ContentMemento(Downloads::Tag downloads);
|
explicit ContentMemento(Downloads::Tag downloads);
|
||||||
@ -240,6 +241,9 @@ public:
|
|||||||
Data::ForumTopic *topic() const {
|
Data::ForumTopic *topic() const {
|
||||||
return _topic;
|
return _topic;
|
||||||
}
|
}
|
||||||
|
Data::SavedSublist *sublist() const {
|
||||||
|
return _sublist;
|
||||||
|
}
|
||||||
UserData *settingsSelf() const {
|
UserData *settingsSelf() const {
|
||||||
return _settingsSelf;
|
return _settingsSelf;
|
||||||
}
|
}
|
||||||
@ -311,6 +315,7 @@ private:
|
|||||||
PeerData * const _peer = nullptr;
|
PeerData * const _peer = nullptr;
|
||||||
const PeerId _migratedPeerId = 0;
|
const PeerId _migratedPeerId = 0;
|
||||||
Data::ForumTopic *_topic = nullptr;
|
Data::ForumTopic *_topic = nullptr;
|
||||||
|
Data::SavedSublist *_sublist = nullptr;
|
||||||
UserData * const _settingsSelf = nullptr;
|
UserData * const _settingsSelf = nullptr;
|
||||||
PeerData * const _storiesPeer = nullptr;
|
PeerData * const _storiesPeer = nullptr;
|
||||||
Stories::Tab _storiesTab = {};
|
Stories::Tab _storiesTab = {};
|
||||||
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
|
|
||||||
#include "ui/search_field_controller.h"
|
#include "ui/search_field_controller.h"
|
||||||
#include "data/data_shared_media.h"
|
#include "data/data_shared_media.h"
|
||||||
|
#include "history/history.h"
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
#include "info/global_media/info_global_media_widget.h"
|
#include "info/global_media/info_global_media_widget.h"
|
||||||
@ -20,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_forum.h"
|
#include "data/data_forum.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "data/data_download_manager.h"
|
#include "data/data_download_manager.h"
|
||||||
@ -35,6 +37,9 @@ Key::Key(not_null<PeerData*> peer) : _value(peer) {
|
|||||||
Key::Key(not_null<Data::ForumTopic*> topic) : _value(topic) {
|
Key::Key(not_null<Data::ForumTopic*> topic) : _value(topic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Key::Key(not_null<Data::SavedSublist*> sublist) : _value(sublist) {
|
||||||
|
}
|
||||||
|
|
||||||
Key::Key(Settings::Tag settings) : _value(settings) {
|
Key::Key(Settings::Tag settings) : _value(settings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +74,8 @@ PeerData *Key::peer() const {
|
|||||||
return *peer;
|
return *peer;
|
||||||
} else if (const auto topic = this->topic()) {
|
} else if (const auto topic = this->topic()) {
|
||||||
return topic->channel();
|
return topic->channel();
|
||||||
|
} else if (const auto sublist = this->sublist()) {
|
||||||
|
return sublist->owningHistory()->peer;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -81,6 +88,14 @@ Data::ForumTopic *Key::topic() const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Data::SavedSublist *Key::sublist() const {
|
||||||
|
if (const auto sublist = std::get_if<not_null<Data::SavedSublist*>>(
|
||||||
|
&_value)) {
|
||||||
|
return *sublist;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
UserData *Key::settingsSelf() const {
|
UserData *Key::settingsSelf() const {
|
||||||
if (const auto tag = std::get_if<Settings::Tag>(&_value)) {
|
if (const auto tag = std::get_if<Settings::Tag>(&_value)) {
|
||||||
return tag->self;
|
return tag->self;
|
||||||
@ -195,6 +210,7 @@ rpl::producer<SparseIdsMergedSlice> AbstractController::mediaSource(
|
|||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
peer()->id,
|
peer()->id,
|
||||||
topicId,
|
topicId,
|
||||||
|
sublist() ? sublist()->sublistPeer()->id : PeerId(),
|
||||||
migratedPeerId(),
|
migratedPeerId(),
|
||||||
aroundId),
|
aroundId),
|
||||||
section().mediaType()),
|
section().mediaType()),
|
||||||
@ -487,6 +503,7 @@ rpl::producer<SparseIdsMergedSlice> Controller::mediaSource(
|
|||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
query.peerId,
|
query.peerId,
|
||||||
query.topicRootId,
|
query.topicRootId,
|
||||||
|
query.monoforumPeerId,
|
||||||
query.migratedPeerId,
|
query.migratedPeerId,
|
||||||
aroundId),
|
aroundId),
|
||||||
query.type),
|
query.type),
|
||||||
|
@ -18,6 +18,7 @@ struct WhoReadList;
|
|||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class ForumTopic;
|
class ForumTopic;
|
||||||
|
class SavedSublist;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@ -94,6 +95,7 @@ class Key {
|
|||||||
public:
|
public:
|
||||||
explicit Key(not_null<PeerData*> peer);
|
explicit Key(not_null<PeerData*> peer);
|
||||||
explicit Key(not_null<Data::ForumTopic*> topic);
|
explicit Key(not_null<Data::ForumTopic*> topic);
|
||||||
|
explicit Key(not_null<Data::SavedSublist*> sublist);
|
||||||
Key(Settings::Tag settings);
|
Key(Settings::Tag settings);
|
||||||
Key(Downloads::Tag downloads);
|
Key(Downloads::Tag downloads);
|
||||||
Key(Stories::Tag stories);
|
Key(Stories::Tag stories);
|
||||||
@ -108,6 +110,7 @@ public:
|
|||||||
|
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
Data::ForumTopic *topic() const;
|
Data::ForumTopic *topic() const;
|
||||||
|
Data::SavedSublist *sublist() const;
|
||||||
UserData *settingsSelf() const;
|
UserData *settingsSelf() const;
|
||||||
bool isDownloads() const;
|
bool isDownloads() const;
|
||||||
bool isGlobalMedia() const;
|
bool isGlobalMedia() const;
|
||||||
@ -135,6 +138,7 @@ private:
|
|||||||
std::variant<
|
std::variant<
|
||||||
not_null<PeerData*>,
|
not_null<PeerData*>,
|
||||||
not_null<Data::ForumTopic*>,
|
not_null<Data::ForumTopic*>,
|
||||||
|
not_null<Data::SavedSublist*>,
|
||||||
Settings::Tag,
|
Settings::Tag,
|
||||||
Downloads::Tag,
|
Downloads::Tag,
|
||||||
Stories::Tag,
|
Stories::Tag,
|
||||||
@ -225,6 +229,9 @@ public:
|
|||||||
[[nodiscard]] Data::ForumTopic *topic() const {
|
[[nodiscard]] Data::ForumTopic *topic() const {
|
||||||
return key().topic();
|
return key().topic();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] Data::SavedSublist *sublist() const {
|
||||||
|
return key().sublist();
|
||||||
|
}
|
||||||
[[nodiscard]] UserData *settingsSelf() const {
|
[[nodiscard]] UserData *settingsSelf() const {
|
||||||
return key().settingsSelf();
|
return key().settingsSelf();
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
|
||||||
@ -48,6 +49,14 @@ Memento::Memento(not_null<Data::ForumTopic*> topic, Section section)
|
|||||||
: Memento(DefaultStack(topic, section)) {
|
: Memento(DefaultStack(topic, section)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::SavedSublist*> sublist)
|
||||||
|
: Memento(sublist, Section::Type::Profile) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::SavedSublist*> sublist, Section section)
|
||||||
|
: Memento(DefaultStack(sublist, section)) {
|
||||||
|
}
|
||||||
|
|
||||||
Memento::Memento(Settings::Tag settings, Section section)
|
Memento::Memento(Settings::Tag settings, Section section)
|
||||||
: Memento(DefaultStack(settings, section)) {
|
: Memento(DefaultStack(settings, section)) {
|
||||||
}
|
}
|
||||||
@ -66,9 +75,12 @@ Memento::Memento(
|
|||||||
Memento::Memento(std::vector<std::shared_ptr<ContentMemento>> stack)
|
Memento::Memento(std::vector<std::shared_ptr<ContentMemento>> stack)
|
||||||
: _stack(std::move(stack)) {
|
: _stack(std::move(stack)) {
|
||||||
auto topics = base::flat_set<not_null<Data::ForumTopic*>>();
|
auto topics = base::flat_set<not_null<Data::ForumTopic*>>();
|
||||||
|
auto sublists = base::flat_set<not_null<Data::SavedSublist*>>();
|
||||||
for (auto &entry : _stack) {
|
for (auto &entry : _stack) {
|
||||||
if (const auto topic = entry->topic()) {
|
if (const auto topic = entry->topic()) {
|
||||||
topics.emplace(topic);
|
topics.emplace(topic);
|
||||||
|
} else if (const auto sublist = entry->sublist()) {
|
||||||
|
sublists.emplace(sublist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &topic : topics) {
|
for (const auto &topic : topics) {
|
||||||
@ -86,6 +98,21 @@ Memento::Memento(std::vector<std::shared_ptr<ContentMemento>> stack)
|
|||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
for (const auto &sublist : sublists) {
|
||||||
|
sublist->destroyed(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
for (auto i = begin(_stack); i != end(_stack);) {
|
||||||
|
if (i->get()->sublist() == sublist) {
|
||||||
|
i = _stack.erase(i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_stack.empty()) {
|
||||||
|
_removeRequests.fire({});
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||||
@ -104,6 +131,14 @@ std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||||
|
not_null<Data::SavedSublist*> sublist,
|
||||||
|
Section section) {
|
||||||
|
auto result = std::vector<std::shared_ptr<ContentMemento>>();
|
||||||
|
result.push_back(DefaultContent(sublist, section));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||||
Settings::Tag settings,
|
Settings::Tag settings,
|
||||||
Section section) {
|
Section section) {
|
||||||
@ -205,6 +240,20 @@ std::shared_ptr<ContentMemento> Memento::DefaultContent(
|
|||||||
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ContentMemento> Memento::DefaultContent(
|
||||||
|
not_null<Data::SavedSublist*> sublist,
|
||||||
|
Section section) {
|
||||||
|
switch (section.type()) {
|
||||||
|
case Section::Type::Profile:
|
||||||
|
return std::make_shared<Profile::Memento>(sublist);
|
||||||
|
case Section::Type::Media:
|
||||||
|
return std::make_shared<Media::Memento>(
|
||||||
|
sublist,
|
||||||
|
section.mediaType());
|
||||||
|
}
|
||||||
|
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<Window::SectionWidget> Memento::createWidget(
|
object_ptr<Window::SectionWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
|
@ -23,6 +23,7 @@ enum class SharedMediaType : signed char;
|
|||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class ForumTopic;
|
class ForumTopic;
|
||||||
|
class SavedSublist;
|
||||||
struct ReactionId;
|
struct ReactionId;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
@ -49,6 +50,8 @@ public:
|
|||||||
Memento(not_null<PeerData*> peer, Section section);
|
Memento(not_null<PeerData*> peer, Section section);
|
||||||
explicit Memento(not_null<Data::ForumTopic*> topic);
|
explicit Memento(not_null<Data::ForumTopic*> topic);
|
||||||
Memento(not_null<Data::ForumTopic*> topic, Section section);
|
Memento(not_null<Data::ForumTopic*> topic, Section section);
|
||||||
|
explicit Memento(not_null<Data::SavedSublist*> sublist);
|
||||||
|
Memento(not_null<Data::SavedSublist*> sublist, Section section);
|
||||||
Memento(Settings::Tag settings, Section section);
|
Memento(Settings::Tag settings, Section section);
|
||||||
Memento(not_null<PollData*> poll, FullMsgId contextId);
|
Memento(not_null<PollData*> poll, FullMsgId contextId);
|
||||||
Memento(
|
Memento(
|
||||||
@ -94,6 +97,9 @@ private:
|
|||||||
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
||||||
not_null<Data::ForumTopic*> topic,
|
not_null<Data::ForumTopic*> topic,
|
||||||
Section section);
|
Section section);
|
||||||
|
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
||||||
|
not_null<Data::SavedSublist*> sublist,
|
||||||
|
Section section);
|
||||||
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
static std::vector<std::shared_ptr<ContentMemento>> DefaultStack(
|
||||||
Settings::Tag settings,
|
Settings::Tag settings,
|
||||||
Section section);
|
Section section);
|
||||||
@ -111,6 +117,9 @@ private:
|
|||||||
static std::shared_ptr<ContentMemento> DefaultContent(
|
static std::shared_ptr<ContentMemento> DefaultContent(
|
||||||
not_null<Data::ForumTopic*> topic,
|
not_null<Data::ForumTopic*> topic,
|
||||||
Section section);
|
Section section);
|
||||||
|
static std::shared_ptr<ContentMemento> DefaultContent(
|
||||||
|
not_null<Data::SavedSublist*> sublist,
|
||||||
|
Section section);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ContentMemento>> _stack;
|
std::vector<std::shared_ptr<ContentMemento>> _stack;
|
||||||
rpl::event_stream<> _removeRequests;
|
rpl::event_stream<> _removeRequests;
|
||||||
|
@ -147,12 +147,18 @@ not_null<Ui::SettingsButton*> AddButton(
|
|||||||
not_null<Window::SessionNavigation*> navigation,
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated,
|
PeerData *migrated,
|
||||||
Type type,
|
Type type,
|
||||||
Ui::MultiSlideTracker &tracker) {
|
Ui::MultiSlideTracker &tracker) {
|
||||||
auto result = AddCountedButton(
|
auto result = AddCountedButton(
|
||||||
parent,
|
parent,
|
||||||
Profile::SharedMediaCountValue(peer, topicRootId, migrated, type),
|
Profile::SharedMediaCountValue(
|
||||||
|
peer,
|
||||||
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
|
migrated,
|
||||||
|
type),
|
||||||
MediaText(type),
|
MediaText(type),
|
||||||
tracker)->entity();
|
tracker)->entity();
|
||||||
const auto separateId = SeparateId(peer, topicRootId, type);
|
const auto separateId = SeparateId(peer, topicRootId, type);
|
||||||
|
@ -42,6 +42,7 @@ using Type = Storage::SharedMediaType;
|
|||||||
not_null<Window::SessionNavigation*> navigation,
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated,
|
PeerData *migrated,
|
||||||
Type type,
|
Type type,
|
||||||
Ui::MultiSlideTracker &tracker);
|
Ui::MultiSlideTracker &tracker);
|
||||||
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "ui/widgets/discrete_sliders.h"
|
#include "ui/widgets/discrete_sliders.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
@ -79,7 +80,11 @@ void InnerWidget::createTypeButtons() {
|
|||||||
auto tracker = Ui::MultiSlideTracker();
|
auto tracker = Ui::MultiSlideTracker();
|
||||||
const auto peer = _controller->key().peer();
|
const auto peer = _controller->key().peer();
|
||||||
const auto topic = _controller->key().topic();
|
const auto topic = _controller->key().topic();
|
||||||
|
const auto sublist = _controller->key().sublist();
|
||||||
const auto topicRootId = topic ? topic->rootId() : MsgId();
|
const auto topicRootId = topic ? topic->rootId() : MsgId();
|
||||||
|
const auto monoforumPeerId = sublist
|
||||||
|
? sublist->sublistPeer()->id
|
||||||
|
: PeerId();
|
||||||
const auto migrated = _controller->migrated();
|
const auto migrated = _controller->migrated();
|
||||||
const auto addMediaButton = [&](
|
const auto addMediaButton = [&](
|
||||||
Type buttonType,
|
Type buttonType,
|
||||||
@ -92,6 +97,7 @@ void InnerWidget::createTypeButtons() {
|
|||||||
_controller,
|
_controller,
|
||||||
peer,
|
peer,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
migrated,
|
migrated,
|
||||||
buttonType,
|
buttonType,
|
||||||
tracker);
|
tracker);
|
||||||
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_download_manager.h"
|
#include "data/data_download_manager.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_item_helpers.h"
|
#include "history/history_item_helpers.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
@ -512,7 +513,7 @@ void ListWidget::openPhoto(not_null<PhotoData*> photo, FullMsgId id) {
|
|||||||
: Data::StoriesContext{ Data::StoriesContextSaved() };
|
: Data::StoriesContext{ Data::StoriesContextSaved() };
|
||||||
_controller->parentController()->openPhoto(
|
_controller->parentController()->openPhoto(
|
||||||
photo,
|
photo,
|
||||||
{ id, topicRootId() },
|
{ id, topicRootId(), monoforumPeerId() },
|
||||||
_controller->storiesPeer() ? &context : nullptr);
|
_controller->storiesPeer() ? &context : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,7 +528,7 @@ void ListWidget::openDocument(
|
|||||||
_controller->parentController()->openDocument(
|
_controller->parentController()->openDocument(
|
||||||
document,
|
document,
|
||||||
showInMediaView,
|
showInMediaView,
|
||||||
{ id, topicRootId() },
|
{ id, topicRootId(), monoforumPeerId() },
|
||||||
_controller->storiesPeer() ? &context : nullptr);
|
_controller->storiesPeer() ? &context : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,6 +797,11 @@ MsgId ListWidget::topicRootId() const {
|
|||||||
return topic ? topic->rootId() : MsgId(0);
|
return topic ? topic->rootId() : MsgId(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PeerId ListWidget::monoforumPeerId() const {
|
||||||
|
const auto sublist = _controller->key().sublist();
|
||||||
|
return sublist ? sublist->sublistPeer()->id : PeerId(0);
|
||||||
|
}
|
||||||
|
|
||||||
QMargins ListWidget::padding() const {
|
QMargins ListWidget::padding() const {
|
||||||
return st::infoMediaMargin;
|
return st::infoMediaMargin;
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,7 @@ private:
|
|||||||
void setupSelectRestriction();
|
void setupSelectRestriction();
|
||||||
|
|
||||||
[[nodiscard]] MsgId topicRootId() const;
|
[[nodiscard]] MsgId topicRootId() const;
|
||||||
|
[[nodiscard]] PeerId monoforumPeerId() const;
|
||||||
|
|
||||||
QMargins padding() const;
|
QMargins padding() const;
|
||||||
bool isItemLayout(
|
bool isItemLayout(
|
||||||
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_overview.h"
|
#include "styles/style_overview.h"
|
||||||
|
|
||||||
@ -40,7 +41,10 @@ Provider::Provider(not_null<AbstractController*> controller)
|
|||||||
, _peer(_controller->key().peer())
|
, _peer(_controller->key().peer())
|
||||||
, _topicRootId(_controller->key().topic()
|
, _topicRootId(_controller->key().topic()
|
||||||
? _controller->key().topic()->rootId()
|
? _controller->key().topic()->rootId()
|
||||||
: 0)
|
: MsgId())
|
||||||
|
, _monoforumPeerId(_controller->key().sublist()
|
||||||
|
? _controller->key().sublist()->sublistPeer()->id
|
||||||
|
: PeerId())
|
||||||
, _migrated(_controller->migrated())
|
, _migrated(_controller->migrated())
|
||||||
, _type(_controller->section().mediaType())
|
, _type(_controller->section().mediaType())
|
||||||
, _slice(sliceKey(_universalAroundId)) {
|
, _slice(sliceKey(_universalAroundId)) {
|
||||||
@ -331,13 +335,23 @@ SparseIdsMergedSlice::Key Provider::sliceKey(
|
|||||||
UniversalMsgId universalId) const {
|
UniversalMsgId universalId) const {
|
||||||
using Key = SparseIdsMergedSlice::Key;
|
using Key = SparseIdsMergedSlice::Key;
|
||||||
if (!_topicRootId && _migrated) {
|
if (!_topicRootId && _migrated) {
|
||||||
return Key(_peer->id, _topicRootId, _migrated->id, universalId);
|
return Key(
|
||||||
|
_peer->id,
|
||||||
|
_topicRootId,
|
||||||
|
_monoforumPeerId,
|
||||||
|
_migrated->id,
|
||||||
|
universalId);
|
||||||
}
|
}
|
||||||
if (universalId < 0) {
|
if (universalId < 0) {
|
||||||
// Convert back to plain id for non-migrated histories.
|
// Convert back to plain id for non-migrated histories.
|
||||||
universalId = universalId + ServerMaxMsgId;
|
universalId = universalId + ServerMaxMsgId;
|
||||||
}
|
}
|
||||||
return Key(_peer->id, _topicRootId, 0, universalId);
|
return Key(
|
||||||
|
_peer->id,
|
||||||
|
_topicRootId,
|
||||||
|
_monoforumPeerId,
|
||||||
|
PeerId(),
|
||||||
|
universalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Provider::itemRemoved(not_null<const HistoryItem*> item) {
|
void Provider::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
|
@ -105,6 +105,7 @@ private:
|
|||||||
|
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
const MsgId _topicRootId = 0;
|
const MsgId _topicRootId = 0;
|
||||||
|
const PeerId _monoforumPeerId = 0;
|
||||||
PeerData * const _migrated = nullptr;
|
PeerData * const _migrated = nullptr;
|
||||||
const Type _type = Type::Photo;
|
const Type _type = Type::Photo;
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
*/
|
*/
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
|
|
||||||
|
#include "history/history.h"
|
||||||
#include "info/media/info_media_inner_widget.h"
|
#include "info/media/info_media_inner_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
@ -17,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
|
|
||||||
@ -70,6 +72,7 @@ Memento::Memento(not_null<Controller*> controller)
|
|||||||
? controller->storiesPeer()
|
? controller->storiesPeer()
|
||||||
: controller->parentController()->session().user()),
|
: controller->parentController()->session().user()),
|
||||||
controller->topic(),
|
controller->topic(),
|
||||||
|
controller->sublist(),
|
||||||
controller->migratedPeerId(),
|
controller->migratedPeerId(),
|
||||||
(controller->section().type() == Section::Type::Downloads
|
(controller->section().type() == Section::Type::Downloads
|
||||||
? Type::File
|
? Type::File
|
||||||
@ -79,23 +82,31 @@ Memento::Memento(not_null<Controller*> controller)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type)
|
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type)
|
||||||
: Memento(peer, nullptr, migratedPeerId, type) {
|
: Memento(peer, nullptr, nullptr, migratedPeerId, type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<Data::ForumTopic*> topic, Type type)
|
Memento::Memento(not_null<Data::ForumTopic*> topic, Type type)
|
||||||
: Memento(topic->channel(), topic, PeerId(), type) {
|
: Memento(topic->channel(), topic, nullptr, PeerId(), type) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::SavedSublist*> sublist, Type type)
|
||||||
|
: Memento(sublist->owningHistory()->peer, nullptr, sublist, PeerId(), type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(
|
Memento::Memento(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Data::ForumTopic *topic,
|
Data::ForumTopic *topic,
|
||||||
|
Data::SavedSublist *sublist,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Type type)
|
Type type)
|
||||||
: ContentMemento(peer, topic, migratedPeerId)
|
: ContentMemento(peer, topic, sublist, migratedPeerId)
|
||||||
, _type(type) {
|
, _type(type) {
|
||||||
_searchState.query.type = type;
|
_searchState.query.type = type;
|
||||||
_searchState.query.peerId = peer->id;
|
_searchState.query.peerId = peer->id;
|
||||||
_searchState.query.topicRootId = topic ? topic->rootId() : 0;
|
_searchState.query.topicRootId = topic ? topic->rootId() : MsgId();
|
||||||
|
_searchState.query.monoforumPeerId = sublist
|
||||||
|
? sublist->sublistPeer()->id
|
||||||
|
: PeerId();
|
||||||
_searchState.query.migratedPeerId = migratedPeerId;
|
_searchState.query.migratedPeerId = migratedPeerId;
|
||||||
if (migratedPeerId) {
|
if (migratedPeerId) {
|
||||||
_searchState.migratedList = Storage::SparseIdsList();
|
_searchState.migratedList = Storage::SparseIdsList();
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
explicit Memento(not_null<Controller*> controller);
|
explicit Memento(not_null<Controller*> controller);
|
||||||
Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type);
|
Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type);
|
||||||
Memento(not_null<Data::ForumTopic*> topic, Type type);
|
Memento(not_null<Data::ForumTopic*> topic, Type type);
|
||||||
|
Memento(not_null<Data::SavedSublist*> sublist, Type type);
|
||||||
|
|
||||||
using SearchState = Api::DelayedSearchController::SavedState;
|
using SearchState = Api::DelayedSearchController::SavedState;
|
||||||
|
|
||||||
@ -92,6 +93,7 @@ private:
|
|||||||
Memento(
|
Memento(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Data::ForumTopic *topic,
|
Data::ForumTopic *topic,
|
||||||
|
Data::SavedSublist *sublist,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Type type);
|
Type type);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ Memento::Memento(not_null<Controller*> controller)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId)
|
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId)
|
||||||
: ContentMemento(peer, nullptr, migratedPeerId) {
|
: ContentMemento(peer, nullptr, nullptr, migratedPeerId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
|
@ -678,7 +678,7 @@ void InnerWidget::restoreState(not_null<Memento*> memento) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<PeerData*> peer)
|
Memento::Memento(not_null<PeerData*> peer)
|
||||||
: ContentMemento(peer, nullptr, PeerId()) {
|
: ContentMemento(peer, nullptr, nullptr, PeerId()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_peer_photo.h"
|
#include "api/api_peer_photo.h"
|
||||||
@ -46,6 +47,7 @@ InnerWidget::InnerWidget(
|
|||||||
, _peer(_controller->key().peer())
|
, _peer(_controller->key().peer())
|
||||||
, _migrated(_controller->migrated())
|
, _migrated(_controller->migrated())
|
||||||
, _topic(_controller->key().topic())
|
, _topic(_controller->key().topic())
|
||||||
|
, _sublist(_controller->key().sublist())
|
||||||
, _content(setupContent(this, origin)) {
|
, _content(setupContent(this, origin)) {
|
||||||
_content->heightValue(
|
_content->heightValue(
|
||||||
) | rpl::start_with_next([this](int height) {
|
) | rpl::start_with_next([this](int height) {
|
||||||
@ -82,7 +84,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
|||||||
|
|
||||||
AddDetails(result, _controller, _peer, _topic, origin);
|
AddDetails(result, _controller, _peer, _topic, origin);
|
||||||
result->add(setupSharedMedia(result.data()));
|
result->add(setupSharedMedia(result.data()));
|
||||||
if (_topic) {
|
if (_topic || _sublist) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -147,7 +149,8 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
|||||||
content,
|
content,
|
||||||
_controller,
|
_controller,
|
||||||
_peer,
|
_peer,
|
||||||
_topic ? _topic->rootId() : 0,
|
_topic ? _topic->rootId() : MsgId(),
|
||||||
|
_sublist ? _sublist->sublistPeer()->id : PeerId(),
|
||||||
_migrated,
|
_migrated,
|
||||||
type,
|
type,
|
||||||
tracker);
|
tracker);
|
||||||
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class ForumTopic;
|
class ForumTopic;
|
||||||
|
class SavedSublist;
|
||||||
class PhotoMedia;
|
class PhotoMedia;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ private:
|
|||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
PeerData * const _migrated = nullptr;
|
PeerData * const _migrated = nullptr;
|
||||||
Data::ForumTopic * const _topic = nullptr;
|
Data::ForumTopic * const _topic = nullptr;
|
||||||
|
Data::SavedSublist * const _sublist = nullptr;
|
||||||
|
|
||||||
PeerData *_reactionGroup = nullptr;
|
PeerData *_reactionGroup = nullptr;
|
||||||
|
|
||||||
|
@ -543,6 +543,7 @@ rpl::producer<int> KickedCountValue(not_null<ChannelData*> channel) {
|
|||||||
rpl::producer<int> SharedMediaCountValue(
|
rpl::producer<int> SharedMediaCountValue(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated,
|
PeerData *migrated,
|
||||||
Storage::SharedMediaType type) {
|
Storage::SharedMediaType type) {
|
||||||
auto aroundId = 0;
|
auto aroundId = 0;
|
||||||
@ -553,6 +554,7 @@ rpl::producer<int> SharedMediaCountValue(
|
|||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
peer->id,
|
peer->id,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
migrated ? migrated->id : 0,
|
migrated ? migrated->id : 0,
|
||||||
aroundId),
|
aroundId),
|
||||||
type),
|
type),
|
||||||
|
@ -113,6 +113,7 @@ struct LinkWithUrl {
|
|||||||
[[nodiscard]] rpl::producer<int> SharedMediaCountValue(
|
[[nodiscard]] rpl::producer<int> SharedMediaCountValue(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
PeerData *migrated,
|
PeerData *migrated,
|
||||||
Storage::SharedMediaType type);
|
Storage::SharedMediaType type);
|
||||||
[[nodiscard]] rpl::producer<int> CommonGroupsCountValue(
|
[[nodiscard]] rpl::producer<int> CommonGroupsCountValue(
|
||||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
|
|
||||||
#include "dialogs/ui/dialogs_stories_content.h"
|
#include "dialogs/ui/dialogs_stories_content.h"
|
||||||
|
#include "history/history.h"
|
||||||
#include "info/profile/info_profile_inner_widget.h"
|
#include "info/profile/info_profile_inner_widget.h"
|
||||||
#include "info/profile/info_profile_members.h"
|
#include "info/profile/info_profile_members.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
@ -15,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
@ -25,6 +27,7 @@ Memento::Memento(not_null<Controller*> controller)
|
|||||||
: Memento(
|
: Memento(
|
||||||
controller->peer(),
|
controller->peer(),
|
||||||
controller->topic(),
|
controller->topic(),
|
||||||
|
controller->sublist(),
|
||||||
controller->migratedPeerId(),
|
controller->migratedPeerId(),
|
||||||
{ v::null }) {
|
{ v::null }) {
|
||||||
}
|
}
|
||||||
@ -33,20 +36,25 @@ Memento::Memento(
|
|||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Origin origin)
|
Origin origin)
|
||||||
: Memento(peer, nullptr, migratedPeerId, origin) {
|
: Memento(peer, nullptr, nullptr, migratedPeerId, origin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(
|
Memento::Memento(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Data::ForumTopic *topic,
|
Data::ForumTopic *topic,
|
||||||
|
Data::SavedSublist *sublist,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Origin origin)
|
Origin origin)
|
||||||
: ContentMemento(peer, topic, migratedPeerId)
|
: ContentMemento(peer, topic, sublist, migratedPeerId)
|
||||||
, _origin(origin) {
|
, _origin(origin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<Data::ForumTopic*> topic)
|
Memento::Memento(not_null<Data::ForumTopic*> topic)
|
||||||
: ContentMemento(topic->channel(), topic, 0) {
|
: ContentMemento(topic->channel(), topic, nullptr, 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Data::SavedSublist*> sublist)
|
||||||
|
: ContentMemento(sublist->owningHistory()->peer, nullptr, sublist, 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Origin origin = { v::null });
|
Origin origin = { v::null });
|
||||||
explicit Memento(not_null<Data::ForumTopic*> topic);
|
explicit Memento(not_null<Data::ForumTopic*> topic);
|
||||||
|
explicit Memento(not_null<Data::SavedSublist*> sublist);
|
||||||
|
|
||||||
object_ptr<ContentWidget> createWidget(
|
object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
@ -56,6 +57,7 @@ private:
|
|||||||
Memento(
|
Memento(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Data::ForumTopic *topic,
|
Data::ForumTopic *topic,
|
||||||
|
Data::SavedSublist *sublist,
|
||||||
PeerId migratedPeerId,
|
PeerId migratedPeerId,
|
||||||
Origin origin);
|
Origin origin);
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ std::shared_ptr<Main::SessionShow> InnerWidget::peerListUiShow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<PeerData*> peer)
|
Memento::Memento(not_null<PeerData*> peer)
|
||||||
: ContentMemento(peer, nullptr, PeerId()) {
|
: ContentMemento(peer, nullptr, nullptr, PeerId()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
|
@ -29,7 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
namespace Info::Saved {
|
namespace Info::Saved {
|
||||||
|
|
||||||
SublistsMemento::SublistsMemento(not_null<Main::Session*> session)
|
SublistsMemento::SublistsMemento(not_null<Main::Session*> session)
|
||||||
: ContentMemento(session->user(), nullptr, PeerId()) {
|
: ContentMemento(session->user(), nullptr, nullptr, PeerId()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section SublistsMemento::section() const {
|
Section SublistsMemento::section() const {
|
||||||
@ -113,6 +113,7 @@ void SublistsWidget::setupOtherTypes() {
|
|||||||
controller(),
|
controller(),
|
||||||
peer,
|
peer,
|
||||||
MsgId(), // topicRootId
|
MsgId(), // topicRootId
|
||||||
|
PeerId(), // monoforumPeerId
|
||||||
nullptr, // migrated
|
nullptr, // migrated
|
||||||
buttonType,
|
buttonType,
|
||||||
tracker);
|
tracker);
|
||||||
|
@ -438,7 +438,7 @@ std::shared_ptr<Main::SessionShow> InnerWidget::peerListUiShow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Memento::Memento(not_null<PeerData*> peer)
|
Memento::Memento(not_null<PeerData*> peer)
|
||||||
: ContentMemento(peer, nullptr, PeerId()) {
|
: ContentMemento(peer, nullptr, nullptr, PeerId()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Memento::section() const {
|
Section Memento::section() const {
|
||||||
|
@ -347,9 +347,9 @@ bool Result::onChoose(Layout::ItemBase *layout) {
|
|||||||
Media::View::OpenRequest Result::openRequest() {
|
Media::View::OpenRequest Result::openRequest() {
|
||||||
using namespace Media::View;
|
using namespace Media::View;
|
||||||
if (_document) {
|
if (_document) {
|
||||||
return OpenRequest(nullptr, _document, nullptr, MsgId());
|
return OpenRequest(nullptr, _document, nullptr, MsgId(), PeerId());
|
||||||
} else if (_photo) {
|
} else if (_photo) {
|
||||||
return OpenRequest(nullptr, _photo, nullptr, MsgId());
|
return OpenRequest(nullptr, _photo, nullptr, MsgId(), PeerId());
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -894,6 +894,7 @@ void Instance::show(
|
|||||||
: nullptr;
|
: nullptr;
|
||||||
const auto item = (HistoryItem*)nullptr;
|
const auto item = (HistoryItem*)nullptr;
|
||||||
const auto topicRootId = MsgId(0);
|
const auto topicRootId = MsgId(0);
|
||||||
|
const auto monoforumPeerId = PeerId(0);
|
||||||
if (event.context.startsWith("-photo")) {
|
if (event.context.startsWith("-photo")) {
|
||||||
const auto id = event.context.mid(6).toULongLong();
|
const auto id = event.context.mid(6).toULongLong();
|
||||||
const auto photo = _shownSession->data().photo(id);
|
const auto photo = _shownSession->data().photo(id);
|
||||||
@ -902,7 +903,8 @@ void Instance::show(
|
|||||||
controller,
|
controller,
|
||||||
photo,
|
photo,
|
||||||
item,
|
item,
|
||||||
topicRootId
|
topicRootId,
|
||||||
|
monoforumPeerId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (event.context.startsWith("-video")) {
|
} else if (event.context.startsWith("-video")) {
|
||||||
@ -913,7 +915,8 @@ void Instance::show(
|
|||||||
controller,
|
controller,
|
||||||
video,
|
video,
|
||||||
item,
|
item,
|
||||||
topicRootId
|
topicRootId,
|
||||||
|
monoforumPeerId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ QByteArray SessionSettings::serialize() const {
|
|||||||
+ sizeof(qint32) * 11
|
+ sizeof(qint32) * 11
|
||||||
+ (_mutePeriods.size() * sizeof(quint64))
|
+ (_mutePeriods.size() * sizeof(quint64))
|
||||||
+ sizeof(qint32) * 2
|
+ sizeof(qint32) * 2
|
||||||
+ _hiddenPinnedMessages.size() * (sizeof(quint64) * 3)
|
+ _hiddenPinnedMessages.size() * (sizeof(quint64) * 4)
|
||||||
+ sizeof(qint32)
|
+ sizeof(qint32)
|
||||||
+ _groupEmojiSectionHidden.size() * sizeof(quint64)
|
+ _groupEmojiSectionHidden.size() * sizeof(quint64)
|
||||||
+ sizeof(qint32) * 2;
|
+ sizeof(qint32) * 2;
|
||||||
@ -68,32 +68,33 @@ QByteArray SessionSettings::serialize() const {
|
|||||||
<< qint32(_archiveInMainMenu.current() ? 1 : 0)
|
<< qint32(_archiveInMainMenu.current() ? 1 : 0)
|
||||||
<< qint32(_skipArchiveInSearch.current() ? 1 : 0)
|
<< qint32(_skipArchiveInSearch.current() ? 1 : 0)
|
||||||
<< qint32(0) // old _mediaLastPlaybackPosition.size());
|
<< qint32(0) // old _mediaLastPlaybackPosition.size());
|
||||||
<< qint32(0) // very old _hiddenPinnedMessages.size());
|
<< qint32(0) // very very old _hiddenPinnedMessages.size());
|
||||||
<< qint32(_dialogsFiltersEnabled ? 1 : 0)
|
<< qint32(_dialogsFiltersEnabled ? 1 : 0)
|
||||||
<< qint32(_supportAllSilent ? 1 : 0)
|
<< qint32(_supportAllSilent ? 1 : 0)
|
||||||
<< qint32(_photoEditorHintShowsCount)
|
<< qint32(_photoEditorHintShowsCount)
|
||||||
<< qint32(0) // old _hiddenPinnedMessages.size());
|
<< qint32(0) // very old _hiddenPinnedMessages.size());
|
||||||
<< qint32(_mutePeriods.size());
|
<< qint32(_mutePeriods.size());
|
||||||
for (const auto &period : _mutePeriods) {
|
for (const auto &period : _mutePeriods) {
|
||||||
stream << quint64(period);
|
stream << quint64(period);
|
||||||
}
|
}
|
||||||
stream
|
stream
|
||||||
<< qint32(0) // old _skipPremiumStickersSet
|
<< qint32(0) // old _skipPremiumStickersSet
|
||||||
<< qint32(_hiddenPinnedMessages.size());
|
<< qint32(0) // old _hiddenPinnedMessages.size());
|
||||||
for (const auto &[key, value] : _hiddenPinnedMessages) {
|
|
||||||
stream
|
|
||||||
<< SerializePeerId(key.peerId)
|
|
||||||
<< qint64(key.topicRootId.bare)
|
|
||||||
<< qint64(value.bare);
|
|
||||||
}
|
|
||||||
stream
|
|
||||||
<< qint32(_groupEmojiSectionHidden.size());
|
<< qint32(_groupEmojiSectionHidden.size());
|
||||||
for (const auto &peerId : _groupEmojiSectionHidden) {
|
for (const auto &peerId : _groupEmojiSectionHidden) {
|
||||||
stream << SerializePeerId(peerId);
|
stream << SerializePeerId(peerId);
|
||||||
}
|
}
|
||||||
stream
|
stream
|
||||||
<< qint32(_lastNonPremiumLimitDownload)
|
<< qint32(_lastNonPremiumLimitDownload)
|
||||||
<< qint32(_lastNonPremiumLimitUpload);
|
<< qint32(_lastNonPremiumLimitUpload)
|
||||||
|
<< qint32(_hiddenPinnedMessages.size());
|
||||||
|
for (const auto &[key, value] : _hiddenPinnedMessages) {
|
||||||
|
stream
|
||||||
|
<< SerializePeerId(key.peerId)
|
||||||
|
<< qint64(key.topicRootId.bare)
|
||||||
|
<< SerializePeerId(key.monoforumPeerId)
|
||||||
|
<< qint64(value.bare);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ensures(result.size() == size);
|
Ensures(result.size() == size);
|
||||||
@ -401,6 +402,7 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) {
|
|||||||
auto count = qint32(0);
|
auto count = qint32(0);
|
||||||
stream >> count;
|
stream >> count;
|
||||||
if (stream.status() == QDataStream::Ok) {
|
if (stream.status() == QDataStream::Ok) {
|
||||||
|
// Legacy.
|
||||||
for (auto i = 0; i != count; ++i) {
|
for (auto i = 0; i != count; ++i) {
|
||||||
auto keyPeerId = quint64();
|
auto keyPeerId = quint64();
|
||||||
auto keyTopicRootId = qint64();
|
auto keyTopicRootId = qint64();
|
||||||
@ -438,6 +440,33 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) {
|
|||||||
>> lastNonPremiumLimitDownload
|
>> lastNonPremiumLimitDownload
|
||||||
>> lastNonPremiumLimitUpload;
|
>> lastNonPremiumLimitUpload;
|
||||||
}
|
}
|
||||||
|
if (!stream.atEnd()) {
|
||||||
|
auto count = qint32(0);
|
||||||
|
stream >> count;
|
||||||
|
if (stream.status() == QDataStream::Ok) {
|
||||||
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
auto keyPeerId = quint64();
|
||||||
|
auto keyTopicRootId = qint64();
|
||||||
|
auto keyMonoforumPeerId = quint64();
|
||||||
|
auto value = qint64();
|
||||||
|
stream
|
||||||
|
>> keyPeerId
|
||||||
|
>> keyTopicRootId
|
||||||
|
>> keyMonoforumPeerId
|
||||||
|
>> value;
|
||||||
|
if (stream.status() != QDataStream::Ok) {
|
||||||
|
LOG(("App Error: "
|
||||||
|
"Bad data for SessionSettings::addFromSerialized()"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hiddenPinnedMessages.emplace(ThreadId{
|
||||||
|
DeserializePeerId(keyPeerId),
|
||||||
|
keyTopicRootId,
|
||||||
|
DeserializePeerId(keyMonoforumPeerId),
|
||||||
|
}, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (stream.status() != QDataStream::Ok) {
|
if (stream.status() != QDataStream::Ok) {
|
||||||
LOG(("App Error: "
|
LOG(("App Error: "
|
||||||
"Bad data for SessionSettings::addFromSerialized()"));
|
"Bad data for SessionSettings::addFromSerialized()"));
|
||||||
@ -595,16 +624,22 @@ rpl::producer<bool> SessionSettings::skipArchiveInSearchChanges() const {
|
|||||||
|
|
||||||
MsgId SessionSettings::hiddenPinnedMessageId(
|
MsgId SessionSettings::hiddenPinnedMessageId(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId) const {
|
MsgId topicRootId,
|
||||||
const auto i = _hiddenPinnedMessages.find({ peerId, topicRootId });
|
PeerId monoforumPeerId) const {
|
||||||
|
const auto i = _hiddenPinnedMessages.find({
|
||||||
|
peerId,
|
||||||
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
|
});
|
||||||
return (i != end(_hiddenPinnedMessages)) ? i->second : 0;
|
return (i != end(_hiddenPinnedMessages)) ? i->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionSettings::setHiddenPinnedMessageId(
|
void SessionSettings::setHiddenPinnedMessageId(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
MsgId msgId) {
|
MsgId msgId) {
|
||||||
const auto id = ThreadId{ peerId, topicRootId };
|
const auto id = ThreadId{ peerId, topicRootId, monoforumPeerId };
|
||||||
if (msgId) {
|
if (msgId) {
|
||||||
_hiddenPinnedMessages[id] = msgId;
|
_hiddenPinnedMessages[id] = msgId;
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,10 +110,12 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] MsgId hiddenPinnedMessageId(
|
[[nodiscard]] MsgId hiddenPinnedMessageId(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId = 0) const;
|
MsgId topicRootId = 0,
|
||||||
|
PeerId monoforumPeerId = 0) const;
|
||||||
void setHiddenPinnedMessageId(
|
void setHiddenPinnedMessageId(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
MsgId msgId);
|
MsgId msgId);
|
||||||
|
|
||||||
[[nodiscard]] bool dialogsFiltersEnabled() const {
|
[[nodiscard]] bool dialogsFiltersEnabled() const {
|
||||||
@ -149,6 +151,7 @@ private:
|
|||||||
struct ThreadId {
|
struct ThreadId {
|
||||||
PeerId peerId;
|
PeerId peerId;
|
||||||
MsgId topicRootId;
|
MsgId topicRootId;
|
||||||
|
PeerId monoforumPeerId;
|
||||||
|
|
||||||
friend inline constexpr auto operator<=>(
|
friend inline constexpr auto operator<=>(
|
||||||
ThreadId,
|
ThreadId,
|
||||||
|
@ -85,6 +85,7 @@ struct Instance::ShuffleData {
|
|||||||
std::vector<UniversalMsgId> playedIds;
|
std::vector<UniversalMsgId> playedIds;
|
||||||
History *history = nullptr;
|
History *history = nullptr;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
History *migrated = nullptr;
|
History *migrated = nullptr;
|
||||||
bool scheduled = false;
|
bool scheduled = false;
|
||||||
int indexInPlayedIds = 0;
|
int indexInPlayedIds = 0;
|
||||||
@ -247,6 +248,7 @@ void Instance::setHistory(
|
|||||||
if (history) {
|
if (history) {
|
||||||
data->history = history->migrateToOrMe();
|
data->history = history->migrateToOrMe();
|
||||||
data->topicRootId = 0;
|
data->topicRootId = 0;
|
||||||
|
data->monoforumPeerId = 0;
|
||||||
data->migrated = data->history->migrateFrom();
|
data->migrated = data->history->migrateFrom();
|
||||||
setSession(data, &history->session());
|
setSession(data, &history->session());
|
||||||
} else {
|
} else {
|
||||||
@ -349,6 +351,7 @@ bool Instance::validPlaylist(not_null<const Data*> data) const {
|
|||||||
const auto inSameDomain = [](const Key &a, const Key &b) {
|
const auto inSameDomain = [](const Key &a, const Key &b) {
|
||||||
return (a.peerId == b.peerId)
|
return (a.peerId == b.peerId)
|
||||||
&& (a.topicRootId == b.topicRootId)
|
&& (a.topicRootId == b.topicRootId)
|
||||||
|
&& (a.monoforumPeerId == b.monoforumPeerId)
|
||||||
&& (a.migratedPeerId == b.migratedPeerId);
|
&& (a.migratedPeerId == b.migratedPeerId);
|
||||||
};
|
};
|
||||||
const auto countDistanceInData = [&](const Key &a, const Key &b) {
|
const auto countDistanceInData = [&](const Key &a, const Key &b) {
|
||||||
@ -422,6 +425,7 @@ auto Instance::playlistKey(not_null<const Data*> data) const
|
|||||||
(item->isScheduled()
|
(item->isScheduled()
|
||||||
? SparseIdsMergedSlice::kScheduledTopicId
|
? SparseIdsMergedSlice::kScheduledTopicId
|
||||||
: data->topicRootId),
|
: data->topicRootId),
|
||||||
|
data->monoforumPeerId,
|
||||||
data->migrated ? data->migrated->peer->id : 0,
|
data->migrated ? data->migrated->peer->id : 0,
|
||||||
universalId);
|
universalId);
|
||||||
}
|
}
|
||||||
@ -479,6 +483,7 @@ auto Instance::playlistOtherKey(not_null<const Data*> data) const
|
|||||||
return SliceKey(
|
return SliceKey(
|
||||||
data->history->peer->id,
|
data->history->peer->id,
|
||||||
data->topicRootId,
|
data->topicRootId,
|
||||||
|
data->monoforumPeerId,
|
||||||
data->migrated ? data->migrated->peer->id : 0,
|
data->migrated ? data->migrated->peer->id : 0,
|
||||||
(data->playlistSlice->skippedBefore() == 0
|
(data->playlistSlice->skippedBefore() == 0
|
||||||
? ServerMaxMsgId - 1
|
? ServerMaxMsgId - 1
|
||||||
@ -905,6 +910,7 @@ void Instance::validateShuffleData(not_null<Data*> data) {
|
|||||||
&& (key->topicRootId == SparseIdsMergedSlice::kScheduledTopicId);
|
&& (key->topicRootId == SparseIdsMergedSlice::kScheduledTopicId);
|
||||||
if (raw->history != data->history
|
if (raw->history != data->history
|
||||||
|| raw->topicRootId != data->topicRootId
|
|| raw->topicRootId != data->topicRootId
|
||||||
|
|| raw->monoforumPeerId != data->monoforumPeerId
|
||||||
|| raw->migrated != data->migrated
|
|| raw->migrated != data->migrated
|
||||||
|| raw->scheduled != scheduled) {
|
|| raw->scheduled != scheduled) {
|
||||||
raw->history = data->history;
|
raw->history = data->history;
|
||||||
@ -962,6 +968,7 @@ void Instance::validateShuffleData(not_null<Data*> data) {
|
|||||||
SliceKey(
|
SliceKey(
|
||||||
raw->history->peer->id,
|
raw->history->peer->id,
|
||||||
raw->topicRootId,
|
raw->topicRootId,
|
||||||
|
raw->monoforumPeerId,
|
||||||
raw->migrated ? raw->migrated->peer->id : 0,
|
raw->migrated ? raw->migrated->peer->id : 0,
|
||||||
last),
|
last),
|
||||||
data->overview),
|
data->overview),
|
||||||
|
@ -194,6 +194,7 @@ private:
|
|||||||
rpl::event_stream<> playlistChanges;
|
rpl::event_stream<> playlistChanges;
|
||||||
History *history = nullptr;
|
History *history = nullptr;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
History *migrated = nullptr;
|
History *migrated = nullptr;
|
||||||
Main::Session *session = nullptr;
|
Main::Session *session = nullptr;
|
||||||
bool isPlaying = false;
|
bool isPlaying = false;
|
||||||
|
@ -30,11 +30,13 @@ public:
|
|||||||
Window::SessionController *controller,
|
Window::SessionController *controller,
|
||||||
not_null<PhotoData*> photo,
|
not_null<PhotoData*> photo,
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
MsgId topicRootId)
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId)
|
||||||
: _controller(controller)
|
: _controller(controller)
|
||||||
, _photo(photo)
|
, _photo(photo)
|
||||||
, _item(item)
|
, _item(item)
|
||||||
, _topicRootId(topicRootId) {
|
, _topicRootId(topicRootId)
|
||||||
|
, _monoforumPeerId(monoforumPeerId) {
|
||||||
}
|
}
|
||||||
OpenRequest(
|
OpenRequest(
|
||||||
Window::SessionController *controller,
|
Window::SessionController *controller,
|
||||||
@ -50,12 +52,14 @@ public:
|
|||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
bool continueStreaming = false,
|
bool continueStreaming = false,
|
||||||
crl::time startTime = 0)
|
crl::time startTime = 0)
|
||||||
: _controller(controller)
|
: _controller(controller)
|
||||||
, _document(document)
|
, _document(document)
|
||||||
, _item(item)
|
, _item(item)
|
||||||
, _topicRootId(topicRootId)
|
, _topicRootId(topicRootId)
|
||||||
|
, _monoforumPeerId(monoforumPeerId)
|
||||||
, _continueStreaming(continueStreaming)
|
, _continueStreaming(continueStreaming)
|
||||||
, _startTime(startTime) {
|
, _startTime(startTime) {
|
||||||
}
|
}
|
||||||
@ -92,6 +96,9 @@ public:
|
|||||||
[[nodiscard]] MsgId topicRootId() const {
|
[[nodiscard]] MsgId topicRootId() const {
|
||||||
return _topicRootId;
|
return _topicRootId;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] PeerId monoforumPeerId() const {
|
||||||
|
return _monoforumPeerId;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] DocumentData *document() const {
|
[[nodiscard]] DocumentData *document() const {
|
||||||
return _document;
|
return _document;
|
||||||
@ -129,6 +136,7 @@ private:
|
|||||||
PeerData *_peer = nullptr;
|
PeerData *_peer = nullptr;
|
||||||
HistoryItem *_item = nullptr;
|
HistoryItem *_item = nullptr;
|
||||||
MsgId _topicRootId = 0;
|
MsgId _topicRootId = 0;
|
||||||
|
PeerId _monoforumPeerId = 0;
|
||||||
std::optional<Data::CloudTheme> _cloudTheme = std::nullopt;
|
std::optional<Data::CloudTheme> _cloudTheme = std::nullopt;
|
||||||
bool _continueStreaming = false;
|
bool _continueStreaming = false;
|
||||||
crl::time _startTime = 0;
|
crl::time _startTime = 0;
|
||||||
|
@ -366,6 +366,7 @@ struct OverlayWidget::PipWrap {
|
|||||||
struct OverlayWidget::ItemContext {
|
struct OverlayWidget::ItemContext {
|
||||||
not_null<HistoryItem*> item;
|
not_null<HistoryItem*> item;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OverlayWidget::StoriesContext {
|
struct OverlayWidget::StoriesContext {
|
||||||
@ -2675,7 +2676,8 @@ void OverlayWidget::handleDocumentClick() {
|
|||||||
findWindow(),
|
findWindow(),
|
||||||
_document,
|
_document,
|
||||||
_message,
|
_message,
|
||||||
_topicRootId);
|
_topicRootId,
|
||||||
|
_monoforumPeerId);
|
||||||
if (_document && _document->loading() && !_radial.animating()) {
|
if (_document && _document->loading() && !_radial.animating()) {
|
||||||
_radial.start(_documentMedia->progress());
|
_radial.start(_documentMedia->progress());
|
||||||
}
|
}
|
||||||
@ -2921,13 +2923,22 @@ void OverlayWidget::showMediaOverview() {
|
|||||||
const auto topic = _topicRootId
|
const auto topic = _topicRootId
|
||||||
? _history->peer->forumTopicFor(_topicRootId)
|
? _history->peer->forumTopicFor(_topicRootId)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
const auto sublist = _monoforumPeerId
|
||||||
|
? _history->peer->monoforumSublistFor(_monoforumPeerId)
|
||||||
|
: nullptr;
|
||||||
if (_topicRootId && !topic) {
|
if (_topicRootId && !topic) {
|
||||||
return;
|
return;
|
||||||
|
} else if (_monoforumPeerId && !sublist) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
window->showSection(_topicRootId
|
window->showSection(_topicRootId
|
||||||
? std::make_shared<Info::Memento>(
|
? std::make_shared<Info::Memento>(
|
||||||
topic,
|
topic,
|
||||||
Info::Section(*overviewType))
|
Info::Section(*overviewType))
|
||||||
|
: _monoforumPeerId
|
||||||
|
? std::make_shared<Info::Memento>(
|
||||||
|
sublist,
|
||||||
|
Info::Section(*overviewType))
|
||||||
: std::make_shared<Info::Memento>(
|
: std::make_shared<Info::Memento>(
|
||||||
_history->peer,
|
_history->peer,
|
||||||
Info::Section(*overviewType)));
|
Info::Section(*overviewType)));
|
||||||
@ -3017,6 +3028,7 @@ auto OverlayWidget::sharedMediaKey() const -> std::optional<SharedMediaKey> {
|
|||||||
return SharedMediaKey{
|
return SharedMediaKey{
|
||||||
_history->peer->id,
|
_history->peer->id,
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
_migrated ? _migrated->peer->id : 0,
|
_migrated ? _migrated->peer->id : 0,
|
||||||
SharedMediaType::ChatPhoto,
|
SharedMediaType::ChatPhoto,
|
||||||
_photo
|
_photo
|
||||||
@ -3032,6 +3044,7 @@ auto OverlayWidget::sharedMediaKey() const -> std::optional<SharedMediaKey> {
|
|||||||
(isScheduled
|
(isScheduled
|
||||||
? SparseIdsMergedSlice::kScheduledTopicId
|
? SparseIdsMergedSlice::kScheduledTopicId
|
||||||
: _topicRootId),
|
: _topicRootId),
|
||||||
|
(isScheduled ? PeerId() : _monoforumPeerId),
|
||||||
_migrated ? _migrated->peer->id : 0,
|
_migrated ? _migrated->peer->id : 0,
|
||||||
type,
|
type,
|
||||||
(_message->history() == _history
|
(_message->history() == _history
|
||||||
@ -4609,6 +4622,7 @@ void OverlayWidget::switchToPip() {
|
|||||||
const auto document = _document;
|
const auto document = _document;
|
||||||
const auto messageId = _message ? _message->fullId() : FullMsgId();
|
const auto messageId = _message ? _message->fullId() : FullMsgId();
|
||||||
const auto topicRootId = _topicRootId;
|
const auto topicRootId = _topicRootId;
|
||||||
|
const auto monoforumPeerId = _monoforumPeerId;
|
||||||
const auto closeAndContinue = [=] {
|
const auto closeAndContinue = [=] {
|
||||||
_showAsPip = false;
|
_showAsPip = false;
|
||||||
show(OpenRequest(
|
show(OpenRequest(
|
||||||
@ -4616,6 +4630,7 @@ void OverlayWidget::switchToPip() {
|
|||||||
document,
|
document,
|
||||||
document->owner().message(messageId),
|
document->owner().message(messageId),
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
true));
|
true));
|
||||||
};
|
};
|
||||||
_showAsPip = true;
|
_showAsPip = true;
|
||||||
@ -5699,9 +5714,9 @@ OverlayWidget::Entity OverlayWidget::entityForCollage(int index) const {
|
|||||||
return { v::null, nullptr };
|
return { v::null, nullptr };
|
||||||
}
|
}
|
||||||
if (const auto document = std::get_if<DocumentData*>(&items[index])) {
|
if (const auto document = std::get_if<DocumentData*>(&items[index])) {
|
||||||
return { *document, _message, _topicRootId };
|
return { *document, _message, _topicRootId, _monoforumPeerId };
|
||||||
} else if (const auto photo = std::get_if<PhotoData*>(&items[index])) {
|
} else if (const auto photo = std::get_if<PhotoData*>(&items[index])) {
|
||||||
return { *photo, _message, _topicRootId };
|
return { *photo, _message, _topicRootId, _monoforumPeerId };
|
||||||
}
|
}
|
||||||
return { v::null, nullptr };
|
return { v::null, nullptr };
|
||||||
}
|
}
|
||||||
@ -5712,12 +5727,12 @@ OverlayWidget::Entity OverlayWidget::entityForItemId(const FullMsgId &itemId) co
|
|||||||
if (const auto item = _session->data().message(itemId)) {
|
if (const auto item = _session->data().message(itemId)) {
|
||||||
if (const auto media = item->media()) {
|
if (const auto media = item->media()) {
|
||||||
if (const auto photo = media->photo()) {
|
if (const auto photo = media->photo()) {
|
||||||
return { photo, item, _topicRootId };
|
return { photo, item, _topicRootId, _monoforumPeerId };
|
||||||
} else if (const auto document = media->document()) {
|
} else if (const auto document = media->document()) {
|
||||||
return { document, item, _topicRootId };
|
return { document, item, _topicRootId, _monoforumPeerId };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { v::null, item, _topicRootId };
|
return { v::null, item, _topicRootId, _monoforumPeerId };
|
||||||
}
|
}
|
||||||
return { v::null, nullptr };
|
return { v::null, nullptr };
|
||||||
}
|
}
|
||||||
@ -5744,6 +5759,9 @@ void OverlayWidget::setContext(
|
|||||||
_history = _message->history();
|
_history = _message->history();
|
||||||
_peer = _history->peer;
|
_peer = _history->peer;
|
||||||
_topicRootId = _peer->isForum() ? item->topicRootId : MsgId();
|
_topicRootId = _peer->isForum() ? item->topicRootId : MsgId();
|
||||||
|
_monoforumPeerId = _peer->amMonoforumAdmin()
|
||||||
|
? item->monoforumPeerId
|
||||||
|
: PeerId();
|
||||||
setStoriesPeer(nullptr);
|
setStoriesPeer(nullptr);
|
||||||
} else if (const auto peer = std::get_if<not_null<PeerData*>>(&context)) {
|
} else if (const auto peer = std::get_if<not_null<PeerData*>>(&context)) {
|
||||||
_peer = *peer;
|
_peer = *peer;
|
||||||
|
@ -170,6 +170,7 @@ private:
|
|||||||
not_null<DocumentData*>> data;
|
not_null<DocumentData*>> data;
|
||||||
HistoryItem *item = nullptr;
|
HistoryItem *item = nullptr;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
};
|
};
|
||||||
enum class SavePhotoVideo {
|
enum class SavePhotoVideo {
|
||||||
None,
|
None,
|
||||||
@ -674,6 +675,7 @@ private:
|
|||||||
History *_migrated = nullptr;
|
History *_migrated = nullptr;
|
||||||
History *_history = nullptr; // if conversation photos or files overview
|
History *_history = nullptr; // if conversation photos or files overview
|
||||||
MsgId _topicRootId = 0;
|
MsgId _topicRootId = 0;
|
||||||
|
PeerId _monoforumPeerId = 0;
|
||||||
PeerData *_peer = nullptr;
|
PeerData *_peer = nullptr;
|
||||||
UserData *_user = nullptr; // if user profile photos overview
|
UserData *_user = nullptr; // if user profile photos overview
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "core/sandbox.h"
|
#include "core/sandbox.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
@ -156,6 +158,7 @@ public:
|
|||||||
void clearAll();
|
void clearAll();
|
||||||
void clearFromItem(not_null<HistoryItem*> item);
|
void clearFromItem(not_null<HistoryItem*> item);
|
||||||
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
||||||
|
void clearFromSublist(not_null<Data::SavedSublist*> sublist);
|
||||||
void clearFromHistory(not_null<History*> history);
|
void clearFromHistory(not_null<History*> history);
|
||||||
void clearFromSession(not_null<Main::Session*> session);
|
void clearFromSession(not_null<Main::Session*> session);
|
||||||
void clearNotification(NotificationId id);
|
void clearNotification(NotificationId id);
|
||||||
@ -367,6 +370,8 @@ Manager::Private::Private(not_null<Manager*> manager)
|
|||||||
.sessionId = dict.lookup_value("session").get_uint64(),
|
.sessionId = dict.lookup_value("session").get_uint64(),
|
||||||
.peerId = PeerId(dict.lookup_value("peer").get_uint64()),
|
.peerId = PeerId(dict.lookup_value("peer").get_uint64()),
|
||||||
.topicRootId = dict.lookup_value("topic").get_int64(),
|
.topicRootId = dict.lookup_value("topic").get_int64(),
|
||||||
|
.monoforumPeerId = dict.lookup_value(
|
||||||
|
"monoforumpeer").get_uint64(),
|
||||||
},
|
},
|
||||||
.msgId = dict.lookup_value("msgid").get_int64(),
|
.msgId = dict.lookup_value("msgid").get_int64(),
|
||||||
};
|
};
|
||||||
@ -531,6 +536,7 @@ void Manager::Private::showNotification(
|
|||||||
.sessionId = peer->session().uniqueId(),
|
.sessionId = peer->session().uniqueId(),
|
||||||
.peerId = peer->id,
|
.peerId = peer->id,
|
||||||
.topicRootId = info.topicRootId,
|
.topicRootId = info.topicRootId,
|
||||||
|
.monoforumPeerId = info.monoforumPeerId,
|
||||||
};
|
};
|
||||||
const auto notificationId = NotificationId{
|
const auto notificationId = NotificationId{
|
||||||
.contextId = key,
|
.contextId = key,
|
||||||
@ -591,6 +597,10 @@ void Manager::Private::showNotification(
|
|||||||
GLib::Variant::new_string("topic"),
|
GLib::Variant::new_string("topic"),
|
||||||
GLib::Variant::new_variant(
|
GLib::Variant::new_variant(
|
||||||
GLib::Variant::new_int64(info.topicRootId.bare))),
|
GLib::Variant::new_int64(info.topicRootId.bare))),
|
||||||
|
GLib::Variant::new_dict_entry(
|
||||||
|
GLib::Variant::new_string("monoforumpeer"),
|
||||||
|
GLib::Variant::new_variant(
|
||||||
|
GLib::Variant::new_uint64(info.monoforumPeerId.value))),
|
||||||
GLib::Variant::new_dict_entry(
|
GLib::Variant::new_dict_entry(
|
||||||
GLib::Variant::new_string("msgid"),
|
GLib::Variant::new_string("msgid"),
|
||||||
GLib::Variant::new_variant(
|
GLib::Variant::new_variant(
|
||||||
@ -809,6 +819,7 @@ void Manager::Private::clearFromItem(not_null<HistoryItem*> item) {
|
|||||||
.sessionId = item->history()->session().uniqueId(),
|
.sessionId = item->history()->session().uniqueId(),
|
||||||
.peerId = item->history()->peer->id,
|
.peerId = item->history()->peer->id,
|
||||||
.topicRootId = item->topicRootId(),
|
.topicRootId = item->topicRootId(),
|
||||||
|
.monoforumPeerId = item->sublistPeerId(),
|
||||||
});
|
});
|
||||||
if (i != _notifications.cend()
|
if (i != _notifications.cend()
|
||||||
&& i->second.remove(item->id)
|
&& i->second.remove(item->id)
|
||||||
@ -825,6 +836,15 @@ void Manager::Private::clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::Private::clearFromSublist(
|
||||||
|
not_null<Data::SavedSublist*> sublist) {
|
||||||
|
_notifications.remove(ContextId{
|
||||||
|
.sessionId = sublist->session().uniqueId(),
|
||||||
|
.peerId = sublist->owningHistory()->peer->id,
|
||||||
|
.monoforumPeerId = sublist->sublistPeer()->id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::Private::clearFromHistory(not_null<History*> history) {
|
void Manager::Private::clearFromHistory(not_null<History*> history) {
|
||||||
const auto sessionId = history->session().uniqueId();
|
const auto sessionId = history->session().uniqueId();
|
||||||
const auto peerId = history->peer->id;
|
const auto peerId = history->peer->id;
|
||||||
@ -889,6 +909,10 @@ void Manager::doClearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
_private->clearFromTopic(topic);
|
_private->clearFromTopic(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::doClearFromSublist(not_null<Data::SavedSublist*> sublist) {
|
||||||
|
_private->clearFromSublist(sublist);
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::doClearFromHistory(not_null<History*> history) {
|
void Manager::doClearFromHistory(not_null<History*> history) {
|
||||||
_private->clearFromHistory(history);
|
_private->clearFromHistory(history);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ protected:
|
|||||||
void doClearAllFast() override;
|
void doClearAllFast() override;
|
||||||
void doClearFromItem(not_null<HistoryItem*> item) override;
|
void doClearFromItem(not_null<HistoryItem*> item) override;
|
||||||
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
||||||
|
void doClearFromSublist(not_null<Data::SavedSublist*> sublist) override;
|
||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
bool doSkipToast() const override;
|
bool doSkipToast() const override;
|
||||||
|
@ -25,6 +25,7 @@ protected:
|
|||||||
void doClearAllFast() override;
|
void doClearAllFast() override;
|
||||||
void doClearFromItem(not_null<HistoryItem*> item) override;
|
void doClearFromItem(not_null<HistoryItem*> item) override;
|
||||||
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
||||||
|
void doClearFromSublist(not_null<Data::SavedSublist*> sublist) override;
|
||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
QString accountNameSeparator() override;
|
QString accountNameSeparator() override;
|
||||||
|
@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "base/platform/mac/base_utilities_mac.h"
|
#include "base/platform/mac/base_utilities_mac.h"
|
||||||
#include "base/random.h"
|
#include "base/random.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
@ -131,6 +133,12 @@ using Manager = Platform::Notifications::Manager;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto notificationTopicRootId = [topicObject longLongValue];
|
const auto notificationTopicRootId = [topicObject longLongValue];
|
||||||
|
NSNumber *monoforumPeerObject = [notificationUserInfo objectForKey:@"monoforumpeer"];
|
||||||
|
if (!monoforumPeerObject) {
|
||||||
|
LOG(("App Error: A notification with unknown monoforum peer was received"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto notificationMonoforumPeerId = [monoforumPeerObject unsignedLongLongValue];
|
||||||
|
|
||||||
NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"];
|
NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"];
|
||||||
const auto notificationMsgId = msgObject ? [msgObject longLongValue] : 0LL;
|
const auto notificationMsgId = msgObject ? [msgObject longLongValue] : 0LL;
|
||||||
@ -140,6 +148,7 @@ using Manager = Platform::Notifications::Manager;
|
|||||||
.sessionId = notificationSessionId,
|
.sessionId = notificationSessionId,
|
||||||
.peerId = PeerId(notificationPeerId),
|
.peerId = PeerId(notificationPeerId),
|
||||||
.topicRootId = MsgId(notificationTopicRootId),
|
.topicRootId = MsgId(notificationTopicRootId),
|
||||||
|
.monoforumPeerId = PeerId(notificationMonoforumPeerId),
|
||||||
},
|
},
|
||||||
.msgId = notificationMsgId,
|
.msgId = notificationMsgId,
|
||||||
};
|
};
|
||||||
@ -210,6 +219,7 @@ public:
|
|||||||
void clearAll();
|
void clearAll();
|
||||||
void clearFromItem(not_null<HistoryItem*> item);
|
void clearFromItem(not_null<HistoryItem*> item);
|
||||||
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
||||||
|
void clearFromSublist(not_null<Data::SavedSublist*> sublist);
|
||||||
void clearFromHistory(not_null<History*> history);
|
void clearFromHistory(not_null<History*> history);
|
||||||
void clearFromSession(not_null<Main::Session*> session);
|
void clearFromSession(not_null<Main::Session*> session);
|
||||||
void updateDelegate();
|
void updateDelegate();
|
||||||
@ -237,6 +247,9 @@ private:
|
|||||||
struct ClearFromTopic {
|
struct ClearFromTopic {
|
||||||
ContextId contextId;
|
ContextId contextId;
|
||||||
};
|
};
|
||||||
|
struct ClearFromSublist {
|
||||||
|
ContextId contextId;
|
||||||
|
}
|
||||||
struct ClearFromHistory {
|
struct ClearFromHistory {
|
||||||
ContextId partialContextId;
|
ContextId partialContextId;
|
||||||
};
|
};
|
||||||
@ -250,6 +263,7 @@ private:
|
|||||||
using ClearTask = std::variant<
|
using ClearTask = std::variant<
|
||||||
ClearFromItem,
|
ClearFromItem,
|
||||||
ClearFromTopic,
|
ClearFromTopic,
|
||||||
|
ClearFromSublist,
|
||||||
ClearFromHistory,
|
ClearFromHistory,
|
||||||
ClearFromSession,
|
ClearFromSession,
|
||||||
ClearAll,
|
ClearAll,
|
||||||
@ -311,6 +325,8 @@ void Manager::Private::showNotification(
|
|||||||
@"peer",
|
@"peer",
|
||||||
[NSNumber numberWithLongLong:info.topicRootId.bare],
|
[NSNumber numberWithLongLong:info.topicRootId.bare],
|
||||||
@"topic",
|
@"topic",
|
||||||
|
[NSNumber numberWithUnsignedLongLong:info.monoforumPeerId.value],
|
||||||
|
@"monoforumpeer",
|
||||||
[NSNumber numberWithLongLong:info.itemId.bare],
|
[NSNumber numberWithLongLong:info.itemId.bare],
|
||||||
@"msgid",
|
@"msgid",
|
||||||
[NSNumber numberWithUnsignedLongLong:_managerId],
|
[NSNumber numberWithUnsignedLongLong:_managerId],
|
||||||
@ -351,6 +367,7 @@ void Manager::Private::clearingThreadLoop() {
|
|||||||
auto clearAll = false;
|
auto clearAll = false;
|
||||||
auto clearFromItems = base::flat_set<NotificationId>();
|
auto clearFromItems = base::flat_set<NotificationId>();
|
||||||
auto clearFromTopics = base::flat_set<ContextId>();
|
auto clearFromTopics = base::flat_set<ContextId>();
|
||||||
|
auto clearFromSublists = base::flat_set<ContextId>();
|
||||||
auto clearFromHistories = base::flat_set<ContextId>();
|
auto clearFromHistories = base::flat_set<ContextId>();
|
||||||
auto clearFromSessions = base::flat_set<uint64>();
|
auto clearFromSessions = base::flat_set<uint64>();
|
||||||
{
|
{
|
||||||
@ -368,6 +385,8 @@ void Manager::Private::clearingThreadLoop() {
|
|||||||
clearFromItems.emplace(value.id);
|
clearFromItems.emplace(value.id);
|
||||||
}, [&](const ClearFromTopic &value) {
|
}, [&](const ClearFromTopic &value) {
|
||||||
clearFromTopics.emplace(value.contextId);
|
clearFromTopics.emplace(value.contextId);
|
||||||
|
}, [&](const ClearFromSublist &value) {
|
||||||
|
clearFromSublists.emplace(value.contextId);
|
||||||
}, [&](const ClearFromHistory &value) {
|
}, [&](const ClearFromHistory &value) {
|
||||||
clearFromHistories.emplace(value.partialContextId);
|
clearFromHistories.emplace(value.partialContextId);
|
||||||
}, [&](const ClearFromSession &value) {
|
}, [&](const ClearFromSession &value) {
|
||||||
@ -395,21 +414,35 @@ void Manager::Private::clearingThreadLoop() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const auto notificationTopicRootId = [topicObject longLongValue];
|
const auto notificationTopicRootId = [topicObject longLongValue];
|
||||||
|
NSNumber *monoforumPeerObject = [notificationUserInfo objectForKey:@"monoforumpeer"];
|
||||||
|
if (!monoforumPeerObject) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto notificationMonoforumPeerId = [monoforumPeerObject unsignedLongLongValue];
|
||||||
NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"];
|
NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"];
|
||||||
const auto msgId = msgObject ? [msgObject longLongValue] : 0LL;
|
const auto msgId = msgObject ? [msgObject longLongValue] : 0LL;
|
||||||
const auto partialContextId = ContextId{
|
const auto partialContextId = ContextId{
|
||||||
.sessionId = notificationSessionId,
|
.sessionId = notificationSessionId,
|
||||||
.peerId = PeerId(notificationPeerId),
|
.peerId = PeerId(notificationPeerId),
|
||||||
};
|
};
|
||||||
const auto contextId = ContextId{
|
const auto contextId = notificationTopicRootId
|
||||||
|
? ContextId{
|
||||||
.sessionId = notificationSessionId,
|
.sessionId = notificationSessionId,
|
||||||
.peerId = PeerId(notificationPeerId),
|
.peerId = PeerId(notificationPeerId),
|
||||||
.topicRootId = MsgId(notificationTopicRootId),
|
.topicRootId = MsgId(notificationTopicRootId),
|
||||||
};
|
}
|
||||||
|
: notificationMonoforumPeerId
|
||||||
|
? ContextId{
|
||||||
|
.sessionId = notificationSessionId,
|
||||||
|
.peerId = PeerId(notificationPeerId),
|
||||||
|
.monoforumPeerId = PeerId(notificationMonoforumPeerId),
|
||||||
|
}
|
||||||
|
: partialContextId;
|
||||||
const auto id = NotificationId{ contextId, MsgId(msgId) };
|
const auto id = NotificationId{ contextId, MsgId(msgId) };
|
||||||
return clearFromSessions.contains(notificationSessionId)
|
return clearFromSessions.contains(notificationSessionId)
|
||||||
|| clearFromHistories.contains(partialContextId)
|
|| clearFromHistories.contains(partialContextId)
|
||||||
|| clearFromTopics.contains(contextId)
|
|| clearFromTopics.contains(contextId)
|
||||||
|
|| clearFromSublists.contains(contextId)
|
||||||
|| (msgId && clearFromItems.contains(id));
|
|| (msgId && clearFromItems.contains(id));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -450,6 +483,7 @@ void Manager::Private::clearFromItem(not_null<HistoryItem*> item) {
|
|||||||
.sessionId = item->history()->session().uniqueId(),
|
.sessionId = item->history()->session().uniqueId(),
|
||||||
.peerId = item->history()->peer->id,
|
.peerId = item->history()->peer->id,
|
||||||
.topicRootId = item->topicRootId(),
|
.topicRootId = item->topicRootId(),
|
||||||
|
.monoforumPeerId = item->sublistPeerId(),
|
||||||
}, item->id });
|
}, item->id });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,6 +495,15 @@ void Manager::Private::clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
} });
|
} });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::Private::clearFromSublist(
|
||||||
|
not_null<Data::SavedSublist*> sublist) {
|
||||||
|
putClearTask(ClearFromSublist{ ContextId{
|
||||||
|
.sessionId = sublist->session().uniqueId(),
|
||||||
|
.peerId = sublist->owningHistory()->peer->id,
|
||||||
|
.monoforumPeerId = sublist->sublistPeer()->id,
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::Private::clearFromHistory(not_null<History*> history) {
|
void Manager::Private::clearFromHistory(not_null<History*> history) {
|
||||||
putClearTask(ClearFromHistory{ ContextId{
|
putClearTask(ClearFromHistory{ ContextId{
|
||||||
.sessionId = history->session().uniqueId(),
|
.sessionId = history->session().uniqueId(),
|
||||||
@ -511,6 +554,10 @@ void Manager::doClearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
_private->clearFromTopic(topic);
|
_private->clearFromTopic(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::doClearFromSublist(not_null<Data::SavedSublist*> sublist) {
|
||||||
|
_private->clearFromSublist(sublist);
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::doClearFromHistory(not_null<History*> history) {
|
void Manager::doClearFromHistory(not_null<History*> history) {
|
||||||
_private->clearFromHistory(history);
|
_private->clearFromHistory(history);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "platform/win/windows_dlls.h"
|
#include "platform/win/windows_dlls.h"
|
||||||
#include "platform/win/specific_win.h"
|
#include "platform/win/specific_win.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
@ -433,6 +435,7 @@ public:
|
|||||||
void clearAll();
|
void clearAll();
|
||||||
void clearFromItem(not_null<HistoryItem*> item);
|
void clearFromItem(not_null<HistoryItem*> item);
|
||||||
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
||||||
|
void clearFromSublist(not_null<Data::SavedSublist*> sublist);
|
||||||
void clearFromHistory(not_null<History*> history);
|
void clearFromHistory(not_null<History*> history);
|
||||||
void clearFromSession(not_null<Main::Session*> session);
|
void clearFromSession(not_null<Main::Session*> session);
|
||||||
void beforeNotificationActivated(NotificationId id);
|
void beforeNotificationActivated(NotificationId id);
|
||||||
@ -508,6 +511,7 @@ void Manager::Private::clearFromItem(not_null<HistoryItem*> item) {
|
|||||||
.sessionId = item->history()->session().uniqueId(),
|
.sessionId = item->history()->session().uniqueId(),
|
||||||
.peerId = item->history()->peer->id,
|
.peerId = item->history()->peer->id,
|
||||||
.topicRootId = item->topicRootId(),
|
.topicRootId = item->topicRootId(),
|
||||||
|
.monoforumPeerId = item->sublistPeerId(),
|
||||||
});
|
});
|
||||||
if (i == _notifications.cend()) {
|
if (i == _notifications.cend()) {
|
||||||
return;
|
return;
|
||||||
@ -544,6 +548,27 @@ void Manager::Private::clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::Private::clearFromSublist(
|
||||||
|
not_null<Data::SavedSublist*> sublist) {
|
||||||
|
if (!_notifier) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto i = _notifications.find(ContextId{
|
||||||
|
.sessionId = sublist->session().uniqueId(),
|
||||||
|
.peerId = sublist->owningHistory()->peer->id,
|
||||||
|
.monoforumPeerId = sublist->sublistPeer()->id,
|
||||||
|
});
|
||||||
|
if (i != _notifications.cend()) {
|
||||||
|
const auto temp = base::take(i->second);
|
||||||
|
_notifications.erase(i);
|
||||||
|
|
||||||
|
for (const auto &[msgId, notification] : temp) {
|
||||||
|
tryHide(notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::Private::clearFromHistory(not_null<History*> history) {
|
void Manager::Private::clearFromHistory(not_null<History*> history) {
|
||||||
if (!_notifier) {
|
if (!_notifier) {
|
||||||
return;
|
return;
|
||||||
@ -626,7 +651,9 @@ void Manager::Private::handleActivation(const ToastActivation &activation) {
|
|||||||
.contextId = ContextId{
|
.contextId = ContextId{
|
||||||
.sessionId = parsed.value("session").toULongLong(),
|
.sessionId = parsed.value("session").toULongLong(),
|
||||||
.peerId = PeerId(parsed.value("peer").toULongLong()),
|
.peerId = PeerId(parsed.value("peer").toULongLong()),
|
||||||
.topicRootId = MsgId(parsed.value("topic").toLongLong())
|
.topicRootId = MsgId(parsed.value("topic").toLongLong()),
|
||||||
|
.monoforumPeerId = PeerId(
|
||||||
|
parsed.value("monoforumpeer").toULongLong()),
|
||||||
},
|
},
|
||||||
.msgId = MsgId(parsed.value("msg").toLongLong()),
|
.msgId = MsgId(parsed.value("msg").toLongLong()),
|
||||||
};
|
};
|
||||||
@ -694,16 +721,18 @@ bool Manager::Private::showNotificationInTryCatch(
|
|||||||
.sessionId = peer->session().uniqueId(),
|
.sessionId = peer->session().uniqueId(),
|
||||||
.peerId = peer->id,
|
.peerId = peer->id,
|
||||||
.topicRootId = info.topicRootId,
|
.topicRootId = info.topicRootId,
|
||||||
|
.monoforumPeerId = info.monoforumPeerId,
|
||||||
};
|
};
|
||||||
const auto notificationId = NotificationId{
|
const auto notificationId = NotificationId{
|
||||||
.contextId = key,
|
.contextId = key,
|
||||||
.msgId = info.itemId,
|
.msgId = info.itemId,
|
||||||
};
|
};
|
||||||
const auto idString = u"pid=%1&session=%2&peer=%3&topic=%4&msg=%5"_q
|
const auto idString = u"pid=%1&session=%2&peer=%3&topic=%4&monoforumpeer=%5&msg=%6"_q
|
||||||
.arg(GetCurrentProcessId())
|
.arg(GetCurrentProcessId())
|
||||||
.arg(key.sessionId)
|
.arg(key.sessionId)
|
||||||
.arg(key.peerId.value)
|
.arg(key.peerId.value)
|
||||||
.arg(info.topicRootId.bare)
|
.arg(info.topicRootId.bare)
|
||||||
|
.arg(info.monoforumPeerId.value)
|
||||||
.arg(info.itemId.bare);
|
.arg(info.itemId.bare);
|
||||||
|
|
||||||
const auto modern = Platform::IsWindows10OrGreater();
|
const auto modern = Platform::IsWindows10OrGreater();
|
||||||
@ -897,6 +926,10 @@ void Manager::doClearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
_private->clearFromTopic(topic);
|
_private->clearFromTopic(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::doClearFromSublist(not_null<Data::SavedSublist*> sublist) {
|
||||||
|
_private->clearFromSublist(sublist);
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::doClearFromHistory(not_null<History*> history) {
|
void Manager::doClearFromHistory(not_null<History*> history) {
|
||||||
_private->clearFromHistory(history);
|
_private->clearFromHistory(history);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ protected:
|
|||||||
void doClearAllFast() override;
|
void doClearAllFast() override;
|
||||||
void doClearFromItem(not_null<HistoryItem*> item) override;
|
void doClearFromItem(not_null<HistoryItem*> item) override;
|
||||||
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
||||||
|
void doClearFromSublist(not_null<Data::SavedSublist*> sublist) override;
|
||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
void onBeforeNotificationActivated(NotificationId id) override;
|
void onBeforeNotificationActivated(NotificationId id) override;
|
||||||
|
@ -1084,6 +1084,7 @@ bool ReadSetting(
|
|||||||
context.sessionSettings().setHiddenPinnedMessageId(
|
context.sessionSettings().setHiddenPinnedMessageId(
|
||||||
DeserializePeerId(i.key()),
|
DeserializePeerId(i.key()),
|
||||||
MsgId(0), // topicRootId
|
MsgId(0), // topicRootId
|
||||||
|
PeerId(0), // monoforumPeerId
|
||||||
MsgId(i.value()));
|
MsgId(i.value()));
|
||||||
}
|
}
|
||||||
context.legacyRead = true;
|
context.legacyRead = true;
|
||||||
|
@ -27,6 +27,7 @@ auto SharedMedia::enforceLists(Key key)
|
|||||||
return SharedMediaSliceUpdate(
|
return SharedMediaSliceUpdate(
|
||||||
key.peerId,
|
key.peerId,
|
||||||
key.topicRootId,
|
key.topicRootId,
|
||||||
|
key.monoforumPeerId,
|
||||||
type,
|
type,
|
||||||
update);
|
update);
|
||||||
}) | rpl::start_to_stream(_sliceUpdated, _lifetime);
|
}) | rpl::start_to_stream(_sliceUpdated, _lifetime);
|
||||||
@ -50,10 +51,20 @@ void SharedMedia::add(SharedMediaAddNew &&query) {
|
|||||||
if (topicIt != end(_lists)) {
|
if (topicIt != end(_lists)) {
|
||||||
addByIt(topicIt);
|
addByIt(topicIt);
|
||||||
}
|
}
|
||||||
|
const auto monoforumPeerIt = query.monoforumPeerId
|
||||||
|
? _lists.find({ query.peerId, MsgId(), query.monoforumPeerId })
|
||||||
|
: end(_lists);
|
||||||
|
if (monoforumPeerIt != end(_lists)) {
|
||||||
|
addByIt(monoforumPeerIt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedMedia::add(SharedMediaAddExisting &&query) {
|
void SharedMedia::add(SharedMediaAddExisting &&query) {
|
||||||
auto peerIt = enforceLists({ query.peerId, query.topicRootId });
|
auto peerIt = enforceLists({
|
||||||
|
query.peerId,
|
||||||
|
query.topicRootId,
|
||||||
|
query.monoforumPeerId,
|
||||||
|
});
|
||||||
for (auto index = 0; index != kSharedMediaTypeCount; ++index) {
|
for (auto index = 0; index != kSharedMediaTypeCount; ++index) {
|
||||||
auto type = static_cast<SharedMediaType>(index);
|
auto type = static_cast<SharedMediaType>(index);
|
||||||
if (query.types.test(type)) {
|
if (query.types.test(type)) {
|
||||||
@ -67,7 +78,11 @@ void SharedMedia::add(SharedMediaAddExisting &&query) {
|
|||||||
void SharedMedia::add(SharedMediaAddSlice &&query) {
|
void SharedMedia::add(SharedMediaAddSlice &&query) {
|
||||||
Expects(IsValidSharedMediaType(query.type));
|
Expects(IsValidSharedMediaType(query.type));
|
||||||
|
|
||||||
auto peerIt = enforceLists({ query.peerId, query.topicRootId });
|
auto peerIt = enforceLists({
|
||||||
|
query.peerId,
|
||||||
|
query.topicRootId,
|
||||||
|
query.monoforumPeerId,
|
||||||
|
});
|
||||||
auto index = static_cast<int>(query.type);
|
auto index = static_cast<int>(query.type);
|
||||||
peerIt->second[index].addSlice(
|
peerIt->second[index].addSlice(
|
||||||
std::move(query.messageIds),
|
std::move(query.messageIds),
|
||||||
@ -90,11 +105,17 @@ void SharedMedia::remove(SharedMediaRemoveOne &&query) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SharedMedia::remove(SharedMediaRemoveAll &&query) {
|
void SharedMedia::remove(SharedMediaRemoveAll &&query) {
|
||||||
auto peerIt = _lists.lower_bound({ query.peerId, query.topicRootId });
|
auto peerIt = _lists.lower_bound({
|
||||||
|
query.peerId,
|
||||||
|
query.topicRootId,
|
||||||
|
query.monoforumPeerId,
|
||||||
|
});
|
||||||
while (peerIt != end(_lists)
|
while (peerIt != end(_lists)
|
||||||
&& peerIt->first.peerId == query.peerId
|
&& peerIt->first.peerId == query.peerId
|
||||||
&& (!query.topicRootId
|
&& (!query.topicRootId
|
||||||
|| peerIt->first.topicRootId == query.topicRootId)) {
|
|| peerIt->first.topicRootId == query.topicRootId)
|
||||||
|
&& (!query.monoforumPeerId
|
||||||
|
|| peerIt->first.monoforumPeerId == query.monoforumPeerId)) {
|
||||||
for (auto index = 0; index != kSharedMediaTypeCount; ++index) {
|
for (auto index = 0; index != kSharedMediaTypeCount; ++index) {
|
||||||
auto type = static_cast<SharedMediaType>(index);
|
auto type = static_cast<SharedMediaType>(index);
|
||||||
if (query.types.test(type)) {
|
if (query.types.test(type)) {
|
||||||
@ -118,13 +139,17 @@ void SharedMedia::invalidate(SharedMediaInvalidateBottom &&query) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SharedMedia::unload(SharedMediaUnloadThread &&query) {
|
void SharedMedia::unload(SharedMediaUnloadThread &&query) {
|
||||||
_lists.erase({ query.peerId, query.topicRootId });
|
_lists.erase({ query.peerId, query.topicRootId, query.monoforumPeerId });
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<SharedMediaResult> SharedMedia::query(SharedMediaQuery &&query) const {
|
rpl::producer<SharedMediaResult> SharedMedia::query(SharedMediaQuery &&query) const {
|
||||||
Expects(IsValidSharedMediaType(query.key.type));
|
Expects(IsValidSharedMediaType(query.key.type));
|
||||||
|
|
||||||
auto peerIt = _lists.find({ query.key.peerId, query.key.topicRootId });
|
auto peerIt = _lists.find({
|
||||||
|
query.key.peerId,
|
||||||
|
query.key.topicRootId,
|
||||||
|
query.key.monoforumPeerId,
|
||||||
|
});
|
||||||
if (peerIt != _lists.end()) {
|
if (peerIt != _lists.end()) {
|
||||||
auto index = static_cast<int>(query.key.type);
|
auto index = static_cast<int>(query.key.type);
|
||||||
return peerIt->second[index].query(SparseIdsListQuery(
|
return peerIt->second[index].query(SparseIdsListQuery(
|
||||||
@ -141,7 +166,11 @@ rpl::producer<SharedMediaResult> SharedMedia::query(SharedMediaQuery &&query) co
|
|||||||
SharedMediaResult SharedMedia::snapshot(const SharedMediaQuery &query) const {
|
SharedMediaResult SharedMedia::snapshot(const SharedMediaQuery &query) const {
|
||||||
Expects(IsValidSharedMediaType(query.key.type));
|
Expects(IsValidSharedMediaType(query.key.type));
|
||||||
|
|
||||||
auto peerIt = _lists.find({ query.key.peerId, query.key.topicRootId });
|
auto peerIt = _lists.find({
|
||||||
|
query.key.peerId,
|
||||||
|
query.key.topicRootId,
|
||||||
|
query.key.monoforumPeerId,
|
||||||
|
});
|
||||||
if (peerIt != _lists.end()) {
|
if (peerIt != _lists.end()) {
|
||||||
auto index = static_cast<int>(query.key.type);
|
auto index = static_cast<int>(query.key.type);
|
||||||
return peerIt->second[index].snapshot(SparseIdsListQuery(
|
return peerIt->second[index].snapshot(SparseIdsListQuery(
|
||||||
@ -155,7 +184,11 @@ SharedMediaResult SharedMedia::snapshot(const SharedMediaQuery &query) const {
|
|||||||
bool SharedMedia::empty(const SharedMediaKey &key) const {
|
bool SharedMedia::empty(const SharedMediaKey &key) const {
|
||||||
Expects(IsValidSharedMediaType(key.type));
|
Expects(IsValidSharedMediaType(key.type));
|
||||||
|
|
||||||
auto peerIt = _lists.find({ key.peerId, key.topicRootId });
|
auto peerIt = _lists.find({
|
||||||
|
key.peerId,
|
||||||
|
key.topicRootId,
|
||||||
|
key.monoforumPeerId,
|
||||||
|
});
|
||||||
if (peerIt != _lists.end()) {
|
if (peerIt != _lists.end()) {
|
||||||
auto index = static_cast<int>(key.type);
|
auto index = static_cast<int>(key.type);
|
||||||
return peerIt->second[index].empty();
|
return peerIt->second[index].empty();
|
||||||
|
@ -42,16 +42,19 @@ struct SharedMediaAddNew {
|
|||||||
SharedMediaAddNew(
|
SharedMediaAddNew(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaTypesMask types,
|
SharedMediaTypesMask types,
|
||||||
MsgId messageId)
|
MsgId messageId)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
, messageId(messageId)
|
, messageId(messageId)
|
||||||
, types(types) {
|
, types(types) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
MsgId messageId = 0;
|
MsgId messageId = 0;
|
||||||
SharedMediaTypesMask types;
|
SharedMediaTypesMask types;
|
||||||
|
|
||||||
@ -61,11 +64,13 @@ struct SharedMediaAddExisting {
|
|||||||
SharedMediaAddExisting(
|
SharedMediaAddExisting(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaTypesMask types,
|
SharedMediaTypesMask types,
|
||||||
MsgId messageId,
|
MsgId messageId,
|
||||||
MsgRange noSkipRange)
|
MsgRange noSkipRange)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
, messageId(messageId)
|
, messageId(messageId)
|
||||||
, noSkipRange(noSkipRange)
|
, noSkipRange(noSkipRange)
|
||||||
, types(types) {
|
, types(types) {
|
||||||
@ -73,6 +78,7 @@ struct SharedMediaAddExisting {
|
|||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
MsgId messageId = 0;
|
MsgId messageId = 0;
|
||||||
MsgRange noSkipRange;
|
MsgRange noSkipRange;
|
||||||
SharedMediaTypesMask types;
|
SharedMediaTypesMask types;
|
||||||
@ -83,12 +89,14 @@ struct SharedMediaAddSlice {
|
|||||||
SharedMediaAddSlice(
|
SharedMediaAddSlice(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
std::vector<MsgId> &&messageIds,
|
std::vector<MsgId> &&messageIds,
|
||||||
MsgRange noSkipRange,
|
MsgRange noSkipRange,
|
||||||
std::optional<int> count = std::nullopt)
|
std::optional<int> count = std::nullopt)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
, messageIds(std::move(messageIds))
|
, messageIds(std::move(messageIds))
|
||||||
, noSkipRange(noSkipRange)
|
, noSkipRange(noSkipRange)
|
||||||
, type(type)
|
, type(type)
|
||||||
@ -97,6 +105,7 @@ struct SharedMediaAddSlice {
|
|||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
std::vector<MsgId> messageIds;
|
std::vector<MsgId> messageIds;
|
||||||
MsgRange noSkipRange;
|
MsgRange noSkipRange;
|
||||||
SharedMediaType type = SharedMediaType::kCount;
|
SharedMediaType type = SharedMediaType::kCount;
|
||||||
@ -135,9 +144,18 @@ struct SharedMediaRemoveAll {
|
|||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
, types(types) {
|
, types(types) {
|
||||||
}
|
}
|
||||||
|
SharedMediaRemoveAll(
|
||||||
|
PeerId peerId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
|
SharedMediaTypesMask types = SharedMediaTypesMask::All())
|
||||||
|
: peerId(peerId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
|
, types(types) {
|
||||||
|
}
|
||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
SharedMediaTypesMask types;
|
SharedMediaTypesMask types;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -154,10 +172,12 @@ struct SharedMediaKey {
|
|||||||
SharedMediaKey(
|
SharedMediaKey(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
MsgId messageId)
|
MsgId messageId)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
, type(type)
|
, type(type)
|
||||||
, messageId(messageId) {
|
, messageId(messageId) {
|
||||||
}
|
}
|
||||||
@ -168,6 +188,7 @@ struct SharedMediaKey {
|
|||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
SharedMediaType type = SharedMediaType::kCount;
|
SharedMediaType type = SharedMediaType::kCount;
|
||||||
MsgId messageId = 0;
|
MsgId messageId = 0;
|
||||||
|
|
||||||
@ -195,16 +216,19 @@ struct SharedMediaSliceUpdate {
|
|||||||
SharedMediaSliceUpdate(
|
SharedMediaSliceUpdate(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
const SparseIdsSliceUpdate &data)
|
const SparseIdsSliceUpdate &data)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId)
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId)
|
||||||
, type(type)
|
, type(type)
|
||||||
, data(data) {
|
, data(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
SharedMediaType type = SharedMediaType::kCount;
|
SharedMediaType type = SharedMediaType::kCount;
|
||||||
SparseIdsSliceUpdate data;
|
SparseIdsSliceUpdate data;
|
||||||
};
|
};
|
||||||
@ -212,13 +236,16 @@ struct SharedMediaSliceUpdate {
|
|||||||
struct SharedMediaUnloadThread {
|
struct SharedMediaUnloadThread {
|
||||||
SharedMediaUnloadThread(
|
SharedMediaUnloadThread(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
MsgId topicRootId)
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId)
|
||||||
: peerId(peerId)
|
: peerId(peerId)
|
||||||
, topicRootId(topicRootId) {
|
, topicRootId(topicRootId)
|
||||||
|
, monoforumPeerId(monoforumPeerId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedMedia {
|
class SharedMedia {
|
||||||
@ -245,6 +272,7 @@ private:
|
|||||||
struct Key {
|
struct Key {
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
|
|
||||||
friend inline constexpr auto operator<=>(Key, Key) = default;
|
friend inline constexpr auto operator<=>(Key, Key) = default;
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/notify/data_notify_settings.h"
|
#include "data/notify/data_notify_settings.h"
|
||||||
#include "data/stickers/data_custom_emoji.h"
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
@ -349,6 +350,15 @@ void System::registerThread(not_null<Data::Thread*> thread) {
|
|||||||
clearFromTopic(topic);
|
clearFromTopic(topic);
|
||||||
}, i->second);
|
}, i->second);
|
||||||
}
|
}
|
||||||
|
} else if (const auto sublist = thread->asSublist()) {
|
||||||
|
const auto &[i, ok] = _watchedSublists.emplace(
|
||||||
|
sublist,
|
||||||
|
rpl::lifetime());
|
||||||
|
if (ok) {
|
||||||
|
sublist->destroyed() | rpl::start_with_next([=] {
|
||||||
|
clearFromSublist(sublist);
|
||||||
|
}, i->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,6 +436,7 @@ void System::clearAll() {
|
|||||||
_waiters.clear();
|
_waiters.clear();
|
||||||
_settingWaiters.clear();
|
_settingWaiters.clear();
|
||||||
_watchedTopics.clear();
|
_watchedTopics.clear();
|
||||||
|
_watchedSublists.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
void System::clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
||||||
@ -445,6 +456,23 @@ void System::clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
showNext();
|
showNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void System::clearFromSublist(not_null<Data::SavedSublist*> sublist) {
|
||||||
|
if (_manager) {
|
||||||
|
_manager->clearFromSublist(sublist);
|
||||||
|
}
|
||||||
|
|
||||||
|
sublist->clearNotifications();
|
||||||
|
_whenMaps.remove(sublist);
|
||||||
|
_whenAlerts.remove(sublist);
|
||||||
|
_waiters.remove(sublist);
|
||||||
|
_settingWaiters.remove(sublist);
|
||||||
|
|
||||||
|
_watchedSublists.remove(sublist);
|
||||||
|
|
||||||
|
_waitTimer.cancel();
|
||||||
|
showNext();
|
||||||
|
}
|
||||||
|
|
||||||
void System::clearForThreadIf(Fn<bool(not_null<Data::Thread*>)> predicate) {
|
void System::clearForThreadIf(Fn<bool(not_null<Data::Thread*>)> predicate) {
|
||||||
for (auto i = _whenMaps.begin(); i != _whenMaps.end();) {
|
for (auto i = _whenMaps.begin(); i != _whenMaps.end();) {
|
||||||
const auto thread = i->first;
|
const auto thread = i->first;
|
||||||
@ -460,6 +488,8 @@ void System::clearForThreadIf(Fn<bool(not_null<Data::Thread*>)> predicate) {
|
|||||||
_settingWaiters.remove(thread);
|
_settingWaiters.remove(thread);
|
||||||
if (const auto topic = thread->asTopic()) {
|
if (const auto topic = thread->asTopic()) {
|
||||||
_watchedTopics.remove(topic);
|
_watchedTopics.remove(topic);
|
||||||
|
} else if (const auto sublist = thread->asSublist()) {
|
||||||
|
_watchedSublists.remove(sublist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto clearFrom = [&](auto &map) {
|
const auto clearFrom = [&](auto &map) {
|
||||||
@ -468,6 +498,8 @@ void System::clearForThreadIf(Fn<bool(not_null<Data::Thread*>)> predicate) {
|
|||||||
if (predicate(thread)) {
|
if (predicate(thread)) {
|
||||||
if (const auto topic = thread->asTopic()) {
|
if (const auto topic = thread->asTopic()) {
|
||||||
_watchedTopics.remove(topic);
|
_watchedTopics.remove(topic);
|
||||||
|
} else if (const auto sublist = thread->asSublist()) {
|
||||||
|
_watchedSublists.remove(sublist);
|
||||||
}
|
}
|
||||||
i = map.erase(i);
|
i = map.erase(i);
|
||||||
} else {
|
} else {
|
||||||
@ -517,6 +549,15 @@ void System::clearIncomingFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
_whenAlerts.remove(topic);
|
_whenAlerts.remove(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void System::clearIncomingFromSublist(
|
||||||
|
not_null<Data::SavedSublist*> sublist) {
|
||||||
|
if (_manager) {
|
||||||
|
_manager->clearFromSublist(sublist);
|
||||||
|
}
|
||||||
|
sublist->clearIncomingNotifications();
|
||||||
|
_whenAlerts.remove(sublist);
|
||||||
|
}
|
||||||
|
|
||||||
void System::clearFromItem(not_null<HistoryItem*> item) {
|
void System::clearFromItem(not_null<HistoryItem*> item) {
|
||||||
if (_manager) {
|
if (_manager) {
|
||||||
_manager->clearFromItem(item);
|
_manager->clearFromItem(item);
|
||||||
@ -533,6 +574,7 @@ void System::clearAllFast() {
|
|||||||
_waiters.clear();
|
_waiters.clear();
|
||||||
_settingWaiters.clear();
|
_settingWaiters.clear();
|
||||||
_watchedTopics.clear();
|
_watchedTopics.clear();
|
||||||
|
_watchedSublists.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::checkDelayed() {
|
void System::checkDelayed() {
|
||||||
@ -1114,10 +1156,14 @@ void Manager::notificationActivated(
|
|||||||
history->peer,
|
history->peer,
|
||||||
id.msgId);
|
id.msgId);
|
||||||
const auto topic = item ? item->topic() : nullptr;
|
const auto topic = item ? item->topic() : nullptr;
|
||||||
|
const auto sublist = item ? item->savedSublist() : nullptr;
|
||||||
if (!options.draft.text.isEmpty()) {
|
if (!options.draft.text.isEmpty()) {
|
||||||
const auto topicRootId = topic
|
const auto topicRootId = topic
|
||||||
? topic->rootId()
|
? topic->rootId()
|
||||||
: id.contextId.topicRootId;
|
: id.contextId.topicRootId;
|
||||||
|
const auto monoforumPeerId = (sublist && sublist->parentChat())
|
||||||
|
? sublist->sublistPeer()->id
|
||||||
|
: id.contextId.monoforumPeerId;
|
||||||
const auto replyToId = (id.msgId > 0
|
const auto replyToId = (id.msgId > 0
|
||||||
&& !history->peer->isUser()
|
&& !history->peer->isUser()
|
||||||
&& id.msgId != topicRootId)
|
&& id.msgId != topicRootId)
|
||||||
@ -1129,6 +1175,7 @@ void Manager::notificationActivated(
|
|||||||
FullReplyTo{
|
FullReplyTo{
|
||||||
.messageId = replyToId,
|
.messageId = replyToId,
|
||||||
.topicRootId = topicRootId,
|
.topicRootId = topicRootId,
|
||||||
|
.monoforumPeerId = monoforumPeerId,
|
||||||
},
|
},
|
||||||
MessageCursor{
|
MessageCursor{
|
||||||
length,
|
length,
|
||||||
@ -1167,13 +1214,13 @@ Window::SessionController *Manager::openNotificationMessage(
|
|||||||
&& item->isRegular()
|
&& item->isRegular()
|
||||||
&& (item->out() || (item->mentionsMe() && !history->peer->isUser()));
|
&& (item->out() || (item->mentionsMe() && !history->peer->isUser()));
|
||||||
const auto topic = item ? item->topic() : nullptr;
|
const auto topic = item ? item->topic() : nullptr;
|
||||||
const auto sublist = (item && item->history()->amMonoforumAdmin())
|
const auto sublist = item ? item->savedSublist() : nullptr;
|
||||||
? item->savedSublist()
|
|
||||||
: nullptr;
|
|
||||||
|
|
||||||
const auto guard = gsl::finally([&] {
|
const auto guard = gsl::finally([&] {
|
||||||
if (topic) {
|
if (topic) {
|
||||||
system()->clearFromTopic(topic);
|
system()->clearFromTopic(topic);
|
||||||
|
} else if (sublist && sublist->parentChat()) {
|
||||||
|
system()->clearFromSublist(sublist);
|
||||||
} else {
|
} else {
|
||||||
system()->clearFromHistory(history);
|
system()->clearFromHistory(history);
|
||||||
}
|
}
|
||||||
@ -1256,6 +1303,10 @@ void Manager::notificationReplied(
|
|||||||
const auto topicRootId = topic
|
const auto topicRootId = topic
|
||||||
? topic->rootId()
|
? topic->rootId()
|
||||||
: id.contextId.topicRootId;
|
: id.contextId.topicRootId;
|
||||||
|
const auto sublist = item ? item->savedSublist() : nullptr;
|
||||||
|
const auto monoforumPeerId = (sublist && sublist->parentChat())
|
||||||
|
? sublist->sublistPeer()->id
|
||||||
|
: id.contextId.monoforumPeerId;
|
||||||
|
|
||||||
auto message = Api::MessageToSend(Api::SendAction(history));
|
auto message = Api::MessageToSend(Api::SendAction(history));
|
||||||
message.textWithTags = reply;
|
message.textWithTags = reply;
|
||||||
@ -1268,6 +1319,7 @@ void Manager::notificationReplied(
|
|||||||
message.action.replyTo = {
|
message.action.replyTo = {
|
||||||
.messageId = { replyToId ? history->peer->id : 0, replyToId },
|
.messageId = { replyToId ? history->peer->id : 0, replyToId },
|
||||||
.topicRootId = topic ? topic->rootId() : 0,
|
.topicRootId = topic ? topic->rootId() : 0,
|
||||||
|
.monoforumPeerId = monoforumPeerId,
|
||||||
};
|
};
|
||||||
message.action.clearDraft = false;
|
message.action.clearDraft = false;
|
||||||
history->session().api().sendMessage(std::move(message));
|
history->session().api().sendMessage(std::move(message));
|
||||||
@ -1293,16 +1345,21 @@ void NativeManager::doShowNotification(NotificationFields &&fields) {
|
|||||||
&& !reactionFrom
|
&& !reactionFrom
|
||||||
&& (item->out() || peer->isSelf())
|
&& (item->out() || peer->isSelf())
|
||||||
&& item->isFromScheduled();
|
&& item->isFromScheduled();
|
||||||
const auto topicWithChat = [&] {
|
const auto subWithChat = [&] {
|
||||||
const auto name = peer->name();
|
const auto name = peer->name();
|
||||||
const auto topic = item->topic();
|
const auto topic = item->topic();
|
||||||
return topic ? (topic->title() + u" ("_q + name + ')') : name;
|
const auto sublist = item->savedSublist();
|
||||||
|
return topic
|
||||||
|
? (topic->title() + u" ("_q + name + ')')
|
||||||
|
: (sublist && sublist->parentChat())
|
||||||
|
? (sublist->sublistPeer()->shortName() + u" ("_q + name + ')')
|
||||||
|
: name;
|
||||||
};
|
};
|
||||||
const auto title = options.hideNameAndPhoto
|
const auto title = options.hideNameAndPhoto
|
||||||
? AppName.utf16()
|
? AppName.utf16()
|
||||||
: (scheduled && peer->isSelf())
|
: (scheduled && peer->isSelf())
|
||||||
? tr::lng_notification_reminder(tr::now)
|
? tr::lng_notification_reminder(tr::now)
|
||||||
: topicWithChat();
|
: subWithChat();
|
||||||
const auto fullTitle = addTargetAccountName(title, &peer->session());
|
const auto fullTitle = addTargetAccountName(title, &peer->session());
|
||||||
const auto subtitle = reactionFrom
|
const auto subtitle = reactionFrom
|
||||||
? (reactionFrom != peer ? reactionFrom->name() : QString())
|
? (reactionFrom != peer ? reactionFrom->name() : QString())
|
||||||
@ -1341,6 +1398,9 @@ void NativeManager::doShowNotification(NotificationFields &&fields) {
|
|||||||
doShowNativeNotification({
|
doShowNativeNotification({
|
||||||
.peer = item->history()->peer,
|
.peer = item->history()->peer,
|
||||||
.topicRootId = item->topicRootId(),
|
.topicRootId = item->topicRootId(),
|
||||||
|
.monoforumPeerId = (item->history()->amMonoforumAdmin()
|
||||||
|
? item->sublistPeerId()
|
||||||
|
: PeerId()),
|
||||||
.itemId = item->id,
|
.itemId = item->id,
|
||||||
.title = scheduled ? WrapFromScheduled(fullTitle) : fullTitle,
|
.title = scheduled ? WrapFromScheduled(fullTitle) : fullTitle,
|
||||||
.subtitle = subtitle,
|
.subtitle = subtitle,
|
||||||
|
@ -17,6 +17,7 @@ class History;
|
|||||||
namespace Data {
|
namespace Data {
|
||||||
class Session;
|
class Session;
|
||||||
class ForumTopic;
|
class ForumTopic;
|
||||||
|
class SavedSublist;
|
||||||
class Thread;
|
class Thread;
|
||||||
struct ItemNotification;
|
struct ItemNotification;
|
||||||
enum class ItemNotificationType;
|
enum class ItemNotificationType;
|
||||||
@ -109,8 +110,10 @@ public:
|
|||||||
void checkDelayed();
|
void checkDelayed();
|
||||||
void schedule(Data::ItemNotification notification);
|
void schedule(Data::ItemNotification notification);
|
||||||
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
void clearFromTopic(not_null<Data::ForumTopic*> topic);
|
||||||
|
void clearFromSublist(not_null<Data::SavedSublist*> sublist);
|
||||||
void clearFromHistory(not_null<History*> history);
|
void clearFromHistory(not_null<History*> history);
|
||||||
void clearIncomingFromTopic(not_null<Data::ForumTopic*> topic);
|
void clearIncomingFromTopic(not_null<Data::ForumTopic*> topic);
|
||||||
|
void clearIncomingFromSublist(not_null<Data::SavedSublist*> sublist);
|
||||||
void clearIncomingFromHistory(not_null<History*> history);
|
void clearIncomingFromHistory(not_null<History*> history);
|
||||||
void clearFromSession(not_null<Main::Session*> session);
|
void clearFromSession(not_null<Main::Session*> session);
|
||||||
void clearFromItem(not_null<HistoryItem*> item);
|
void clearFromItem(not_null<HistoryItem*> item);
|
||||||
@ -221,6 +224,9 @@ private:
|
|||||||
base::flat_map<
|
base::flat_map<
|
||||||
not_null<Data::ForumTopic*>,
|
not_null<Data::ForumTopic*>,
|
||||||
rpl::lifetime> _watchedTopics;
|
rpl::lifetime> _watchedTopics;
|
||||||
|
base::flat_map<
|
||||||
|
not_null<Data::SavedSublist*>,
|
||||||
|
rpl::lifetime> _watchedSublists;
|
||||||
|
|
||||||
int _lastForwardedCount = 0;
|
int _lastForwardedCount = 0;
|
||||||
uint64 _lastHistorySessionId = 0;
|
uint64 _lastHistorySessionId = 0;
|
||||||
@ -237,6 +243,7 @@ public:
|
|||||||
uint64 sessionId = 0;
|
uint64 sessionId = 0;
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
|
|
||||||
friend inline auto operator<=>(
|
friend inline auto operator<=>(
|
||||||
const ContextId&,
|
const ContextId&,
|
||||||
@ -279,6 +286,9 @@ public:
|
|||||||
void clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
void clearFromTopic(not_null<Data::ForumTopic*> topic) {
|
||||||
doClearFromTopic(topic);
|
doClearFromTopic(topic);
|
||||||
}
|
}
|
||||||
|
void clearFromSublist(not_null<Data::SavedSublist*> sublist) {
|
||||||
|
doClearFromSublist(sublist);
|
||||||
|
}
|
||||||
void clearFromHistory(not_null<History*> history) {
|
void clearFromHistory(not_null<History*> history) {
|
||||||
doClearFromHistory(history);
|
doClearFromHistory(history);
|
||||||
}
|
}
|
||||||
@ -341,6 +351,8 @@ protected:
|
|||||||
virtual void doClearAllFast() = 0;
|
virtual void doClearAllFast() = 0;
|
||||||
virtual void doClearFromItem(not_null<HistoryItem*> item) = 0;
|
virtual void doClearFromItem(not_null<HistoryItem*> item) = 0;
|
||||||
virtual void doClearFromTopic(not_null<Data::ForumTopic*> topic) = 0;
|
virtual void doClearFromTopic(not_null<Data::ForumTopic*> topic) = 0;
|
||||||
|
virtual void doClearFromSublist(
|
||||||
|
not_null<Data::SavedSublist*> sublist) = 0;
|
||||||
virtual void doClearFromHistory(not_null<History*> history) = 0;
|
virtual void doClearFromHistory(not_null<History*> history) = 0;
|
||||||
virtual void doClearFromSession(not_null<Main::Session*> session) = 0;
|
virtual void doClearFromSession(not_null<Main::Session*> session) = 0;
|
||||||
[[nodiscard]] virtual bool doSkipToast() const = 0;
|
[[nodiscard]] virtual bool doSkipToast() const = 0;
|
||||||
@ -377,6 +389,7 @@ public:
|
|||||||
struct NotificationInfo {
|
struct NotificationInfo {
|
||||||
not_null<PeerData*> peer;
|
not_null<PeerData*> peer;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
MsgId itemId = 0;
|
MsgId itemId = 0;
|
||||||
QString title;
|
QString title;
|
||||||
QString subtitle;
|
QString subtitle;
|
||||||
@ -426,6 +439,8 @@ protected:
|
|||||||
}
|
}
|
||||||
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override {
|
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override {
|
||||||
}
|
}
|
||||||
|
void doClearFromSublist(not_null<Data::SavedSublist*> sublist) override {
|
||||||
|
}
|
||||||
void doClearFromHistory(not_null<History*> history) override {
|
void doClearFromHistory(not_null<History*> history) override {
|
||||||
}
|
}
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override {
|
void doClearFromSession(not_null<Main::Session*> session) override {
|
||||||
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/power_saving.h"
|
#include "ui/power_saving.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/stickers/data_custom_emoji.h"
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
@ -236,6 +237,7 @@ void Manager::showNextFromQueue() {
|
|||||||
this,
|
this,
|
||||||
queued.history,
|
queued.history,
|
||||||
queued.topicRootId,
|
queued.topicRootId,
|
||||||
|
queued.monoforumPeerId,
|
||||||
queued.peer,
|
queued.peer,
|
||||||
queued.author,
|
queued.author,
|
||||||
queued.item,
|
queued.item,
|
||||||
@ -383,7 +385,25 @@ void Manager::doClearFromTopic(not_null<Data::ForumTopic*> topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto ¬ification : _notifications) {
|
for (const auto ¬ification : _notifications) {
|
||||||
if (notification->unlinkHistory(history, topicRootId)) {
|
if (notification->unlinkHistory(history, topicRootId, PeerId())) {
|
||||||
|
_positionsOutdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
showNextFromQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::doClearFromSublist(not_null<Data::SavedSublist*> sublist) {
|
||||||
|
const auto history = sublist->owningHistory();
|
||||||
|
const auto sublistPeerId = sublist->sublistPeer()->id;
|
||||||
|
for (auto i = _queuedNotifications.begin(); i != _queuedNotifications.cend();) {
|
||||||
|
if (i->history == history && i->monoforumPeerId == sublistPeerId) {
|
||||||
|
i = _queuedNotifications.erase(i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto ¬ification : _notifications) {
|
||||||
|
if (notification->unlinkHistory(history, MsgId(), sublistPeerId)) {
|
||||||
_positionsOutdated = true;
|
_positionsOutdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,6 +638,7 @@ Notification::Notification(
|
|||||||
not_null<Manager*> manager,
|
not_null<Manager*> manager,
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
@ -633,6 +654,8 @@ Notification::Notification(
|
|||||||
, _history(history)
|
, _history(history)
|
||||||
, _topic(history->peer->forumTopicFor(topicRootId))
|
, _topic(history->peer->forumTopicFor(topicRootId))
|
||||||
, _topicRootId(topicRootId)
|
, _topicRootId(topicRootId)
|
||||||
|
, _sublist(history->peer->monoforumSublistFor(monoforumPeerId))
|
||||||
|
, _monoforumPeerId(monoforumPeerId)
|
||||||
, _userpicView(_peer->createUserpicView())
|
, _userpicView(_peer->createUserpicView())
|
||||||
, _author(author)
|
, _author(author)
|
||||||
, _reaction(reaction)
|
, _reaction(reaction)
|
||||||
@ -1149,10 +1172,14 @@ void Notification::changeHeight(int newHeight) {
|
|||||||
manager()->changeNotificationHeight(this, newHeight);
|
manager()->changeNotificationHeight(this, newHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Notification::unlinkHistory(History *history, MsgId topicRootId) {
|
bool Notification::unlinkHistory(
|
||||||
|
History *history,
|
||||||
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId) {
|
||||||
const auto unlink = _history
|
const auto unlink = _history
|
||||||
&& (history == _history || !history)
|
&& (history == _history || !history)
|
||||||
&& (topicRootId == _topicRootId || !topicRootId);
|
&& (topicRootId == _topicRootId || !topicRootId)
|
||||||
|
&& (monoforumPeerId == _monoforumPeerId || !monoforumPeerId);
|
||||||
if (unlink) {
|
if (unlink) {
|
||||||
hideFast();
|
hideFast();
|
||||||
_history = nullptr;
|
_history = nullptr;
|
||||||
|
@ -70,6 +70,7 @@ private:
|
|||||||
void doClearAll() override;
|
void doClearAll() override;
|
||||||
void doClearAllFast() override;
|
void doClearAllFast() override;
|
||||||
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
void doClearFromTopic(not_null<Data::ForumTopic*> topic) override;
|
||||||
|
void doClearFromSublist(not_null<Data::SavedSublist*> sublist) override;
|
||||||
void doClearFromHistory(not_null<History*> history) override;
|
void doClearFromHistory(not_null<History*> history) override;
|
||||||
void doClearFromSession(not_null<Main::Session*> session) override;
|
void doClearFromSession(not_null<Main::Session*> session) override;
|
||||||
void doClearFromItem(not_null<HistoryItem*> item) override;
|
void doClearFromItem(not_null<HistoryItem*> item) override;
|
||||||
@ -111,6 +112,7 @@ private:
|
|||||||
|
|
||||||
not_null<History*> history;
|
not_null<History*> history;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
PeerId monoforumPeerId = 0;
|
||||||
not_null<PeerData*> peer;
|
not_null<PeerData*> peer;
|
||||||
Data::ReactionId reaction;
|
Data::ReactionId reaction;
|
||||||
QString author;
|
QString author;
|
||||||
@ -203,6 +205,7 @@ public:
|
|||||||
not_null<Manager*> manager,
|
not_null<Manager*> manager,
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
@ -231,7 +234,10 @@ public:
|
|||||||
|
|
||||||
// Called only by Manager.
|
// Called only by Manager.
|
||||||
bool unlinkItem(HistoryItem *del);
|
bool unlinkItem(HistoryItem *del);
|
||||||
bool unlinkHistory(History *history = nullptr, MsgId topicRootId = 0);
|
bool unlinkHistory(
|
||||||
|
History *history = nullptr,
|
||||||
|
MsgId topicRootId = 0,
|
||||||
|
PeerId monoforumPeerId = 0);
|
||||||
bool unlinkSession(not_null<Main::Session*> session);
|
bool unlinkSession(not_null<Main::Session*> session);
|
||||||
bool checkLastInput(
|
bool checkLastInput(
|
||||||
bool hasReplyingNotifications,
|
bool hasReplyingNotifications,
|
||||||
@ -285,6 +291,8 @@ private:
|
|||||||
History *_history = nullptr;
|
History *_history = nullptr;
|
||||||
Data::ForumTopic *_topic = nullptr;
|
Data::ForumTopic *_topic = nullptr;
|
||||||
MsgId _topicRootId = 0;
|
MsgId _topicRootId = 0;
|
||||||
|
Data::SavedSublist *_sublist = nullptr;
|
||||||
|
PeerId _monoforumPeerId = 0;
|
||||||
Ui::PeerUserpicView _userpicView;
|
Ui::PeerUserpicView _userpicView;
|
||||||
QString _author;
|
QString _author;
|
||||||
Data::ReactionId _reaction;
|
Data::ReactionId _reaction;
|
||||||
|
@ -3040,14 +3040,18 @@ void HidePinnedBar(
|
|||||||
not_null<Window::SessionNavigation*> navigation,
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
Fn<void()> onHidden) {
|
Fn<void()> onHidden) {
|
||||||
const auto callback = crl::guard(navigation, [=](Fn<void()> &&close) {
|
const auto callback = crl::guard(navigation, [=](Fn<void()> &&close) {
|
||||||
close();
|
close();
|
||||||
auto &session = peer->session();
|
auto &session = peer->session();
|
||||||
const auto migrated = topicRootId ? nullptr : peer->migrateFrom();
|
const auto migrated = (topicRootId || monoforumPeerId)
|
||||||
|
? nullptr
|
||||||
|
: peer->migrateFrom();
|
||||||
const auto top = Data::ResolveTopPinnedId(
|
const auto top = Data::ResolveTopPinnedId(
|
||||||
peer,
|
peer,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
migrated);
|
migrated);
|
||||||
const auto universal = !top
|
const auto universal = !top
|
||||||
? MsgId(0)
|
? MsgId(0)
|
||||||
@ -3058,6 +3062,7 @@ void HidePinnedBar(
|
|||||||
session.settings().setHiddenPinnedMessageId(
|
session.settings().setHiddenPinnedMessageId(
|
||||||
peer->id,
|
peer->id,
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
monoforumPeerId,
|
||||||
universal);
|
universal);
|
||||||
session.saveSettingsDelayed();
|
session.saveSettingsDelayed();
|
||||||
if (onHidden) {
|
if (onHidden) {
|
||||||
@ -3091,6 +3096,7 @@ void UnpinAllMessages(
|
|||||||
const auto history = strong->owningHistory();
|
const auto history = strong->owningHistory();
|
||||||
const auto topicRootId = strong->topicRootId();
|
const auto topicRootId = strong->topicRootId();
|
||||||
const auto sublist = strong->asSublist();
|
const auto sublist = strong->asSublist();
|
||||||
|
const auto monoforumPeerId = strong->monoforumPeerId();
|
||||||
using Flag = MTPmessages_UnpinAllMessages::Flag;
|
using Flag = MTPmessages_UnpinAllMessages::Flag;
|
||||||
api->request(MTPmessages_UnpinAllMessages(
|
api->request(MTPmessages_UnpinAllMessages(
|
||||||
MTP_flags((topicRootId ? Flag::f_top_msg_id : Flag())
|
MTP_flags((topicRootId ? Flag::f_top_msg_id : Flag())
|
||||||
@ -3104,7 +3110,7 @@ void UnpinAllMessages(
|
|||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
self(self);
|
self(self);
|
||||||
} else {
|
} else {
|
||||||
history->unpinMessagesFor(topicRootId);
|
history->unpinMessagesFor(topicRootId, monoforumPeerId);
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
};
|
};
|
||||||
|
@ -218,6 +218,7 @@ void HidePinnedBar(
|
|||||||
not_null<Window::SessionNavigation*> navigation,
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
|
PeerId monoforumPeerId,
|
||||||
Fn<void()> onHidden);
|
Fn<void()> onHidden);
|
||||||
void UnpinAllMessages(
|
void UnpinAllMessages(
|
||||||
not_null<Window::SessionNavigation*> navigation,
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
|
@ -2927,8 +2927,12 @@ void SessionController::openPhoto(
|
|||||||
if (openSharedStory(item) || openFakeItemStory(message.id, stories)) {
|
if (openSharedStory(item) || openFakeItemStory(message.id, stories)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_window->openInMediaView(
|
_window->openInMediaView(Media::View::OpenRequest(
|
||||||
Media::View::OpenRequest(this, photo, item, message.topicRootId));
|
this,
|
||||||
|
photo,
|
||||||
|
item,
|
||||||
|
message.topicRootId,
|
||||||
|
message.monoforumPeerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionController::openPhoto(
|
void SessionController::openPhoto(
|
||||||
@ -2963,11 +2967,17 @@ void SessionController::openDocument(
|
|||||||
document,
|
document,
|
||||||
item,
|
item,
|
||||||
message.topicRootId,
|
message.topicRootId,
|
||||||
|
message.monoforumPeerId,
|
||||||
false,
|
false,
|
||||||
usedTimestamp));
|
usedTimestamp));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Data::ResolveDocument(this, document, item, message.topicRootId);
|
Data::ResolveDocument(
|
||||||
|
this,
|
||||||
|
document,
|
||||||
|
item,
|
||||||
|
message.topicRootId,
|
||||||
|
message.monoforumPeerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionController::openSharedStory(HistoryItem *item) {
|
bool SessionController::openSharedStory(HistoryItem *item) {
|
||||||
|
@ -523,6 +523,7 @@ public:
|
|||||||
struct MessageContext {
|
struct MessageContext {
|
||||||
FullMsgId id;
|
FullMsgId id;
|
||||||
MsgId topicRootId;
|
MsgId topicRootId;
|
||||||
|
PeerId monoforumPeerId;
|
||||||
};
|
};
|
||||||
void openPhoto(
|
void openPhoto(
|
||||||
not_null<PhotoData*> photo,
|
not_null<PhotoData*> photo,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user