mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-26 23:43:06 +02:00
Support drafts in monoforum sublists.
This commit is contained in:
parent
b2c01991a6
commit
f65556acb7
30 changed files with 488 additions and 208 deletions
|
@ -47,6 +47,7 @@ void Polls::create(
|
|||
const auto topicRootId = action.replyTo.messageId
|
||||
? action.replyTo.topicRootId
|
||||
: 0;
|
||||
const auto monoforumPeerId = action.replyTo.monoforumPeerId;
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
if (action.replyTo) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
|
||||
|
@ -54,9 +55,9 @@ void Polls::create(
|
|||
const auto clearCloudDraft = action.clearDraft;
|
||||
if (clearCloudDraft) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
||||
history->clearLocalDraft(topicRootId);
|
||||
history->clearCloudDraft(topicRootId);
|
||||
history->startSavingCloudDraft(topicRootId);
|
||||
history->clearLocalDraft(topicRootId, monoforumPeerId);
|
||||
history->clearCloudDraft(topicRootId, monoforumPeerId);
|
||||
history->startSavingCloudDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||
const auto starsPaid = std::min(
|
||||
|
@ -106,6 +107,7 @@ void Polls::create(
|
|||
if (clearCloudDraft) {
|
||||
history->finishSavingCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
}
|
||||
_session->changes().historyUpdated(
|
||||
|
@ -118,6 +120,7 @@ void Polls::create(
|
|||
if (clearCloudDraft) {
|
||||
history->finishSavingCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
}
|
||||
fail();
|
||||
|
|
|
@ -2687,13 +2687,22 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
|||
const auto &data = update.c_updateDraftMessage();
|
||||
const auto peerId = peerFromMTP(data.vpeer());
|
||||
const auto topicRootId = data.vtop_msg_id().value_or_empty();
|
||||
const auto monoforumPeerId = data.vsaved_peer_id()
|
||||
? peerFromMTP(*data.vsaved_peer_id())
|
||||
: PeerId();
|
||||
data.vdraft().match([&](const MTPDdraftMessage &data) {
|
||||
Data::ApplyPeerCloudDraft(&session(), peerId, topicRootId, data);
|
||||
Data::ApplyPeerCloudDraft(
|
||||
&session(),
|
||||
peerId,
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
data);
|
||||
}, [&](const MTPDdraftMessageEmpty &data) {
|
||||
Data::ClearPeerCloudDraft(
|
||||
&session(),
|
||||
peerId,
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
data.vdate().value_or_empty());
|
||||
});
|
||||
} break;
|
||||
|
|
|
@ -2064,8 +2064,13 @@ void ApiWrap::saveCurrentDraftToCloud() {
|
|||
_session->local().writeDrafts(history);
|
||||
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
const auto localDraft = history->localDraft(topicRootId);
|
||||
const auto cloudDraft = history->cloudDraft(topicRootId);
|
||||
const auto monoforumPeerId = thread->monoforumPeerId();
|
||||
const auto localDraft = history->localDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId);
|
||||
const auto cloudDraft = history->cloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId);
|
||||
if (!Data::DraftsAreEqual(localDraft, cloudDraft)
|
||||
&& !_session->supportMode()) {
|
||||
saveDraftToCloudDelayed(thread);
|
||||
|
@ -2088,15 +2093,22 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
|
||||
const auto history = thread->owningHistory();
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
auto cloudDraft = history->cloudDraft(topicRootId);
|
||||
auto localDraft = history->localDraft(topicRootId);
|
||||
const auto monoforumPeerId = thread->monoforumPeerId();
|
||||
auto cloudDraft = history->cloudDraft(topicRootId, monoforumPeerId);
|
||||
auto localDraft = history->localDraft(topicRootId, monoforumPeerId);
|
||||
if (cloudDraft && cloudDraft->saveRequestId) {
|
||||
request(base::take(cloudDraft->saveRequestId)).cancel();
|
||||
}
|
||||
if (!_session->supportMode()) {
|
||||
cloudDraft = history->createCloudDraft(topicRootId, localDraft);
|
||||
cloudDraft = history->createCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
localDraft);
|
||||
} else if (!cloudDraft) {
|
||||
cloudDraft = history->createCloudDraft(topicRootId, nullptr);
|
||||
cloudDraft = history->createCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
auto flags = MTPmessages_SaveDraft::Flags(0);
|
||||
|
@ -2106,7 +2118,9 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
} else if (!cloudDraft->webpage.url.isEmpty()) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_media;
|
||||
}
|
||||
if (cloudDraft->reply.messageId || cloudDraft->reply.topicRootId) {
|
||||
if (cloudDraft->reply.messageId
|
||||
|| cloudDraft->reply.topicRootId
|
||||
|| cloudDraft->reply.monoforumPeerId) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_reply_to;
|
||||
}
|
||||
if (!textWithTags.tags.isEmpty()) {
|
||||
|
@ -2117,7 +2131,7 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
history->startSavingCloudDraft(topicRootId);
|
||||
history->startSavingCloudDraft(topicRootId, monoforumPeerId);
|
||||
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
||||
MTP_flags(flags),
|
||||
ReplyToForMTP(history, cloudDraft->reply),
|
||||
|
@ -2132,11 +2146,15 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
const auto requestId = response.requestId;
|
||||
history->finishSavingCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
if (const auto cloudDraft = history->cloudDraft(topicRootId)) {
|
||||
const auto cloudDraft = history->cloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId);
|
||||
if (cloudDraft) {
|
||||
if (cloudDraft->saveRequestId == requestId) {
|
||||
cloudDraft->saveRequestId = 0;
|
||||
history->draftSavedToCloud(topicRootId);
|
||||
history->draftSavedToCloud(topicRootId, monoforumPeerId);
|
||||
}
|
||||
}
|
||||
const auto i = _draftsSaveRequestIds.find(weak);
|
||||
|
@ -2149,10 +2167,14 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
const auto requestId = response.requestId;
|
||||
history->finishSavingCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
if (const auto cloudDraft = history->cloudDraft(topicRootId)) {
|
||||
const auto cloudDraft = history->cloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId);
|
||||
if (cloudDraft) {
|
||||
if (cloudDraft->saveRequestId == requestId) {
|
||||
history->clearCloudDraft(topicRootId);
|
||||
history->clearCloudDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
}
|
||||
const auto i = _draftsSaveRequestIds.find(weak);
|
||||
|
@ -3223,7 +3245,10 @@ void ApiWrap::sendAction(const SendAction &action) {
|
|||
void ApiWrap::finishForwarding(const SendAction &action) {
|
||||
const auto history = action.history;
|
||||
const auto topicRootId = action.replyTo.topicRootId;
|
||||
auto toForward = history->resolveForwardDraft(topicRootId);
|
||||
const auto monoforumPeerId = action.replyTo.monoforumPeerId;
|
||||
auto toForward = history->resolveForwardDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId);
|
||||
if (!toForward.items.empty()) {
|
||||
const auto error = GetErrorForSending(
|
||||
history->peer,
|
||||
|
@ -3236,7 +3261,7 @@ void ApiWrap::finishForwarding(const SendAction &action) {
|
|||
}
|
||||
|
||||
forwardMessages(std::move(toForward), action);
|
||||
history->setForwardDraft(topicRootId, {});
|
||||
history->setForwardDraft(topicRootId, monoforumPeerId, {});
|
||||
}
|
||||
|
||||
_session->data().sendHistoryChangeNotifications();
|
||||
|
@ -3728,6 +3753,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
|
||||
const auto clearCloudDraft = action.clearDraft;
|
||||
const auto draftTopicRootId = action.replyTo.topicRootId;
|
||||
const auto draftMonoforumPeerId = action.replyTo.monoforumPeerId;
|
||||
const auto replyTo = action.replyTo.messageId
|
||||
? peer->owner().message(action.replyTo.messageId)
|
||||
: nullptr;
|
||||
|
@ -3837,8 +3863,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
if (clearCloudDraft) {
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
||||
history->clearCloudDraft(draftTopicRootId);
|
||||
history->startSavingCloudDraft(draftTopicRootId);
|
||||
history->clearCloudDraft(draftTopicRootId, draftMonoforumPeerId);
|
||||
history->startSavingCloudDraft(
|
||||
draftTopicRootId,
|
||||
draftMonoforumPeerId);
|
||||
}
|
||||
const auto sendAs = action.options.sendAs;
|
||||
if (sendAs) {
|
||||
|
@ -3884,6 +3912,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
if (clearCloudDraft) {
|
||||
history->finishSavingCloudDraft(
|
||||
draftTopicRootId,
|
||||
draftMonoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
}
|
||||
};
|
||||
|
@ -3898,6 +3927,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
if (clearCloudDraft) {
|
||||
history->finishSavingCloudDraft(
|
||||
draftTopicRootId,
|
||||
draftMonoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
}
|
||||
};
|
||||
|
@ -4016,6 +4046,7 @@ void ApiWrap::sendInlineResult(
|
|||
const auto topicRootId = action.replyTo.messageId
|
||||
? action.replyTo.topicRootId
|
||||
: 0;
|
||||
const auto monoforumPeerId = action.replyTo.monoforumPeerId;
|
||||
|
||||
using SendFlag = MTPmessages_SendInlineBotResult::Flag;
|
||||
auto flags = NewMessageFlags(peer);
|
||||
|
@ -4068,8 +4099,8 @@ void ApiWrap::sendInlineResult(
|
|||
.postAuthor = NewMessagePostAuthor(action),
|
||||
});
|
||||
|
||||
history->clearCloudDraft(topicRootId);
|
||||
history->startSavingCloudDraft(topicRootId);
|
||||
history->clearCloudDraft(topicRootId, monoforumPeerId);
|
||||
history->startSavingCloudDraft(topicRootId, monoforumPeerId);
|
||||
|
||||
auto &histories = history->owner().histories();
|
||||
histories.sendPreparedMessage(
|
||||
|
@ -4090,6 +4121,7 @@ void ApiWrap::sendInlineResult(
|
|||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
history->finishSavingCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
if (done) {
|
||||
done(true);
|
||||
|
@ -4098,6 +4130,7 @@ void ApiWrap::sendInlineResult(
|
|||
sendMessageFail(error, peer, randomId, newId);
|
||||
history->finishSavingCloudDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
if (done) {
|
||||
done(false);
|
||||
|
|
|
@ -70,10 +70,11 @@ void ApplyPeerCloudDraft(
|
|||
not_null<Main::Session*> session,
|
||||
PeerId peerId,
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
const MTPDdraftMessage &draft) {
|
||||
const auto history = session->data().history(peerId);
|
||||
const auto date = draft.vdate().v;
|
||||
if (history->skipCloudDraftUpdate(topicRootId, date)) {
|
||||
if (history->skipCloudDraftUpdate(topicRootId, monoforumPeerId, date)) {
|
||||
return;
|
||||
}
|
||||
const auto textWithTags = TextWithTags{
|
||||
|
@ -87,6 +88,7 @@ void ApplyPeerCloudDraft(
|
|||
? ReplyToFromMTP(history, *draft.vreply_to())
|
||||
: FullReplyTo();
|
||||
replyTo.topicRootId = topicRootId;
|
||||
replyTo.monoforumPeerId = monoforumPeerId;
|
||||
auto webpage = WebPageDraft{
|
||||
.invert = draft.is_invert_media(),
|
||||
.removed = draft.is_no_webpage(),
|
||||
|
@ -112,21 +114,22 @@ void ApplyPeerCloudDraft(
|
|||
cloudDraft->date = date;
|
||||
|
||||
history->setCloudDraft(std::move(cloudDraft));
|
||||
history->applyCloudDraft(topicRootId);
|
||||
history->applyCloudDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
|
||||
void ClearPeerCloudDraft(
|
||||
not_null<Main::Session*> session,
|
||||
PeerId peerId,
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
TimeId date) {
|
||||
const auto history = session->data().history(peerId);
|
||||
if (history->skipCloudDraftUpdate(topicRootId, date)) {
|
||||
if (history->skipCloudDraftUpdate(topicRootId, monoforumPeerId, date)) {
|
||||
return;
|
||||
}
|
||||
|
||||
history->clearCloudDraft(topicRootId);
|
||||
history->applyCloudDraft(topicRootId);
|
||||
history->clearCloudDraft(topicRootId, monoforumPeerId);
|
||||
history->applyCloudDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
|
||||
void SetChatLinkDraft(not_null<PeerData*> peer, TextWithEntities draft) {
|
||||
|
@ -146,12 +149,16 @@ void SetChatLinkDraft(not_null<PeerData*> peer, TextWithEntities draft) {
|
|||
};
|
||||
const auto history = peer->owner().history(peer->id);
|
||||
const auto topicRootId = MsgId();
|
||||
const auto monoforumPeerId = PeerId();
|
||||
history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
textWithTags,
|
||||
FullReplyTo{ .topicRootId = topicRootId },
|
||||
FullReplyTo{
|
||||
.topicRootId = topicRootId,
|
||||
.monoforumPeerId = monoforumPeerId,
|
||||
},
|
||||
cursor,
|
||||
Data::WebPageDraft()));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->clearLocalEditDraft(topicRootId, monoforumPeerId);
|
||||
history->session().changes().entryUpdated(
|
||||
history,
|
||||
Data::EntryUpdate::Flag::LocalDraftSet);
|
||||
|
|
|
@ -23,11 +23,13 @@ void ApplyPeerCloudDraft(
|
|||
not_null<Main::Session*> session,
|
||||
PeerId peerId,
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
const MTPDdraftMessage &draft);
|
||||
void ClearPeerCloudDraft(
|
||||
not_null<Main::Session*> session,
|
||||
PeerId peerId,
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
TimeId date);
|
||||
|
||||
struct WebPageDraft {
|
||||
|
@ -72,22 +74,38 @@ public:
|
|||
[[nodiscard]] static constexpr DraftKey None() {
|
||||
return 0;
|
||||
}
|
||||
[[nodiscard]] static constexpr DraftKey Local(MsgId topicRootId) {
|
||||
return (topicRootId < 0 || topicRootId >= ServerMaxMsgId)
|
||||
[[nodiscard]] static constexpr DraftKey Local(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
return Invalid(topicRootId, monoforumPeerId)
|
||||
? None()
|
||||
: (topicRootId ? topicRootId.bare : kLocalDraftIndex);
|
||||
: (topicRootId
|
||||
? topicRootId.bare
|
||||
: monoforumPeerId
|
||||
? (monoforumPeerId.value + kMonoforumDraftBit)
|
||||
: kLocalDraftIndex);
|
||||
}
|
||||
[[nodiscard]] static constexpr DraftKey LocalEdit(MsgId topicRootId) {
|
||||
return (topicRootId < 0 || topicRootId >= ServerMaxMsgId)
|
||||
[[nodiscard]] static constexpr DraftKey LocalEdit(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
return Invalid(topicRootId, monoforumPeerId)
|
||||
? None()
|
||||
: ((topicRootId ? topicRootId.bare : kLocalDraftIndex)
|
||||
+ kEditDraftShift);
|
||||
: (kEditDraftShift
|
||||
+ (topicRootId
|
||||
? topicRootId.bare
|
||||
: monoforumPeerId
|
||||
? (monoforumPeerId.value + kMonoforumDraftBit)
|
||||
: kLocalDraftIndex));
|
||||
}
|
||||
[[nodiscard]] static constexpr DraftKey Cloud(MsgId topicRootId) {
|
||||
return (topicRootId < 0 || topicRootId >= ServerMaxMsgId)
|
||||
[[nodiscard]] static constexpr DraftKey Cloud(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
return Invalid(topicRootId, monoforumPeerId)
|
||||
? None()
|
||||
: topicRootId
|
||||
? (kCloudDraftShift + topicRootId.bare)
|
||||
: monoforumPeerId
|
||||
? (kCloudDraftShift + monoforumPeerId.value + kMonoforumDraftBit)
|
||||
: kCloudDraftIndex;
|
||||
}
|
||||
[[nodiscard]] static constexpr DraftKey Scheduled() {
|
||||
|
@ -120,40 +138,62 @@ public:
|
|||
return !value
|
||||
? None()
|
||||
: (value == kLocalDraftIndex + kEditDraftShiftOld)
|
||||
? LocalEdit(0)
|
||||
? LocalEdit(MsgId(), PeerId())
|
||||
: (value == kScheduledDraftIndex + kEditDraftShiftOld)
|
||||
? ScheduledEdit()
|
||||
: (value > 0 && value < 0x4000'0000)
|
||||
? Local(MsgId(value))
|
||||
? Local(MsgId(value), PeerId())
|
||||
: (value > kEditDraftShiftOld
|
||||
&& value < kEditDraftShiftOld + 0x4000'000)
|
||||
? LocalEdit(int64(value - kEditDraftShiftOld))
|
||||
? LocalEdit(MsgId(int64(value - kEditDraftShiftOld)), PeerId())
|
||||
: None();
|
||||
}
|
||||
[[nodiscard]] constexpr bool isLocal() const {
|
||||
return (_value == kLocalDraftIndex)
|
||||
|| (_value > 0 && _value < ServerMaxMsgId.bare);
|
||||
|| (_value > 0
|
||||
&& (_value & kMonoforumDraftMask) < ServerMaxMsgId.bare);
|
||||
}
|
||||
[[nodiscard]] constexpr bool isCloud() const {
|
||||
return (_value == kCloudDraftIndex)
|
||||
|| (_value > kCloudDraftShift
|
||||
&& _value < kCloudDraftShift + ServerMaxMsgId.bare);
|
||||
|| ((_value & kMonoforumDraftMask) > kCloudDraftShift
|
||||
&& ((_value & kMonoforumDraftMask)
|
||||
< kCloudDraftShift + ServerMaxMsgId.bare));
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr MsgId topicRootId() const {
|
||||
const auto max = ServerMaxMsgId.bare;
|
||||
if (_value > kCloudDraftShift && _value < kCloudDraftShift + max) {
|
||||
if (_value & kMonoforumDraftBit) {
|
||||
return 0;
|
||||
} else if ((_value > kCloudDraftShift)
|
||||
&& (_value < kCloudDraftShift + max)) {
|
||||
return (_value - kCloudDraftShift);
|
||||
} else if (_value > kEditDraftShift && _value < kEditDraftShift + max) {
|
||||
} else if ((_value > kEditDraftShift)
|
||||
&& (_value < kEditDraftShift + max)) {
|
||||
return (_value - kEditDraftShift);
|
||||
} else if (_value > 0 && _value < max) {
|
||||
return _value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr PeerId monoforumPeerId() const {
|
||||
const auto max = ServerMaxMsgId.bare;
|
||||
const auto value = _value & kMonoforumDraftMask;
|
||||
if (!(_value & kMonoforumDraftBit)) {
|
||||
return 0;
|
||||
} else if ((value > kCloudDraftShift)
|
||||
&& (value < kCloudDraftShift + max)) {
|
||||
return PeerId(UserId(value - kCloudDraftShift));
|
||||
} else if ((value > kEditDraftShift)
|
||||
&& (value < kEditDraftShift + max)) {
|
||||
return PeerId(UserId(value - kEditDraftShift));
|
||||
} else if (value > 0 && value < max) {
|
||||
return PeerId(UserId(value));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
friend inline constexpr auto operator<=>(DraftKey, DraftKey) = default;
|
||||
friend inline constexpr bool operator==(DraftKey, DraftKey) = default;
|
||||
|
||||
inline explicit operator bool() const {
|
||||
return _value != 0;
|
||||
|
@ -163,9 +203,20 @@ private:
|
|||
constexpr DraftKey(int64 value) : _value(value) {
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr bool Invalid(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
return (topicRootId < 0)
|
||||
|| (topicRootId >= ServerMaxMsgId)
|
||||
|| !peerIsUser(monoforumPeerId)
|
||||
|| (monoforumPeerId.value >= ServerMaxMsgId);
|
||||
}
|
||||
|
||||
static constexpr auto kLocalDraftIndex = -1;
|
||||
static constexpr auto kCloudDraftIndex = -2;
|
||||
static constexpr auto kScheduledDraftIndex = -3;
|
||||
static constexpr auto kMonoforumDraftBit = (int64(1) << 60);
|
||||
static constexpr auto kMonoforumDraftMask = (kMonoforumDraftBit - 1);
|
||||
static constexpr auto kEditDraftShift = ServerMaxMsgId.bare;
|
||||
static constexpr auto kCloudDraftShift = 2 * ServerMaxMsgId.bare;
|
||||
static constexpr auto kShortcutDraftShift = 3 * ServerMaxMsgId.bare;
|
||||
|
|
|
@ -73,7 +73,7 @@ Forum::~Forum() {
|
|||
const auto peerId = _history->peer->id;
|
||||
for (const auto &[rootId, topic] : _topics) {
|
||||
storage.unload(Storage::SharedMediaUnloadThread(peerId, rootId));
|
||||
_history->setForwardDraft(rootId, {});
|
||||
_history->setForwardDraft(rootId, PeerId(), {});
|
||||
|
||||
const auto raw = topic.get();
|
||||
changes.topicRemoved(raw);
|
||||
|
@ -197,7 +197,7 @@ void Forum::applyTopicDeleted(MsgId rootId) {
|
|||
session().storage().unload(Storage::SharedMediaUnloadThread(
|
||||
_history->peer->id,
|
||||
rootId));
|
||||
_history->setForwardDraft(rootId, {});
|
||||
_history->setForwardDraft(rootId, PeerId(), {});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -406,6 +406,7 @@ void ForumTopic::applyTopic(const MTPDforumTopic &data) {
|
|||
&session(),
|
||||
channel()->id,
|
||||
_rootId,
|
||||
PeerId(),
|
||||
data);
|
||||
}, [](const MTPDdraftMessageEmpty&) {});
|
||||
}
|
||||
|
@ -709,7 +710,7 @@ void ForumTopic::requestChatListMessage() {
|
|||
|
||||
TimeId ForumTopic::adjustedChatListTimeId() const {
|
||||
const auto result = chatListTimeId();
|
||||
if (const auto draft = history()->cloudDraft(_rootId)) {
|
||||
if (const auto draft = history()->cloudDraft(_rootId, PeerId())) {
|
||||
if (!Data::DraftIsNull(draft) && !session().supportMode()) {
|
||||
return std::max(result, draft->date);
|
||||
}
|
||||
|
|
|
@ -180,11 +180,11 @@ struct FullReplyTo {
|
|||
PeerId monoforumPeerId = 0;
|
||||
int quoteOffset = 0;
|
||||
|
||||
[[nodiscard]] bool valid() const {
|
||||
return messageId || (storyId && storyId.peer) || monoforumPeerId;
|
||||
[[nodiscard]] bool replying() const {
|
||||
return messageId || (storyId && storyId.peer);
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return valid();
|
||||
return replying() || monoforumPeerId;
|
||||
}
|
||||
friend inline auto operator<=>(FullReplyTo, FullReplyTo) = default;
|
||||
friend inline bool operator==(FullReplyTo, FullReplyTo) = default;
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_saved_messages.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
|
@ -47,7 +48,15 @@ SavedMessages::SavedMessages(
|
|||
}
|
||||
}
|
||||
|
||||
SavedMessages::~SavedMessages() = default;
|
||||
SavedMessages::~SavedMessages() {
|
||||
auto &changes = session().changes();
|
||||
for (const auto &[peer, sublist] : _sublists) {
|
||||
_owningHistory->setForwardDraft(MsgId(), peer->id, {});
|
||||
|
||||
const auto raw = sublist.get();
|
||||
changes.entryRemoved(raw);
|
||||
}
|
||||
}
|
||||
|
||||
bool SavedMessages::supported() const {
|
||||
return !_unsupported;
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_messages.h"
|
||||
#include "data/data_peer.h"
|
||||
|
@ -695,15 +696,18 @@ void SavedSublist::subscribeToUnreadChanges() {
|
|||
void SavedSublist::applyMonoforumDialog(
|
||||
const MTPDmonoForumDialog &data,
|
||||
not_null<HistoryItem*> topItem) {
|
||||
//if (const auto draft = data.vdraft()) { // #TODO monoforum
|
||||
// draft->match([&](const MTPDdraftMessage &data) {
|
||||
// Data::ApplyPeerCloudDraft(
|
||||
// &session(),
|
||||
// channel()->id,
|
||||
// _rootId,
|
||||
// data);
|
||||
// }, [](const MTPDdraftMessageEmpty&) {});
|
||||
//}
|
||||
if (const auto parent = parentChat()) {
|
||||
if (const auto draft = data.vdraft()) {
|
||||
draft->match([&](const MTPDdraftMessage &data) {
|
||||
Data::ApplyPeerCloudDraft(
|
||||
&session(),
|
||||
parent->id,
|
||||
MsgId(),
|
||||
sublistPeer()->id,
|
||||
data);
|
||||
}, [](const MTPDdraftMessageEmpty&) {});
|
||||
}
|
||||
}
|
||||
|
||||
setInboxReadTill(
|
||||
data.vread_inbox_max_id().v,
|
||||
|
@ -712,6 +716,18 @@ void SavedSublist::applyMonoforumDialog(
|
|||
applyMaybeLast(topItem);
|
||||
}
|
||||
|
||||
TimeId SavedSublist::adjustedChatListTimeId() const {
|
||||
const auto result = chatListTimeId();
|
||||
const auto monoforumPeerId = sublistPeer()->id;
|
||||
const auto history = _parent->owningHistory();
|
||||
if (const auto draft = history->cloudDraft(MsgId(), monoforumPeerId)) {
|
||||
if (!Data::DraftIsNull(draft) && !session().supportMode()) {
|
||||
return std::max(result, draft->date);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
rpl::producer<> SavedSublist::changes() const {
|
||||
return _listChanges.events();
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
void readTillEnd();
|
||||
void requestChatListMessage();
|
||||
|
||||
TimeId adjustedChatListTimeId() const override;
|
||||
|
||||
int fixedOnTopIndex() const override;
|
||||
bool shouldBeInChatList() const override;
|
||||
Dialogs::UnreadState chatListUnreadState() const override;
|
||||
|
|
|
@ -32,6 +32,13 @@ MsgId Thread::topicRootId() const {
|
|||
return MsgId();
|
||||
}
|
||||
|
||||
PeerId Thread::monoforumPeerId() const {
|
||||
if (const auto sublist = asSublist()) {
|
||||
return sublist->sublistPeer()->id;
|
||||
}
|
||||
return PeerId();
|
||||
}
|
||||
|
||||
PeerData *Thread::maybeSublistPeer() const {
|
||||
if (const auto sublist = asSublist()) {
|
||||
return sublist->sublistPeer();
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
return const_cast<Thread*>(this)->owningHistory();
|
||||
}
|
||||
[[nodiscard]] MsgId topicRootId() const;
|
||||
[[nodiscard]] PeerId monoforumPeerId() const;
|
||||
[[nodiscard]] PeerData *maybeSublistPeer() const;
|
||||
[[nodiscard]] not_null<PeerData*> peer() const;
|
||||
[[nodiscard]] PeerNotifySettings ¬ify();
|
||||
|
|
|
@ -382,8 +382,6 @@ struct ForwardDraft {
|
|||
const ForwardDraft&) = default;
|
||||
};
|
||||
|
||||
using ForwardDrafts = base::flat_map<MsgId, ForwardDraft>;
|
||||
|
||||
struct ResolvedForwardDraft {
|
||||
HistoryItemsList items;
|
||||
ForwardOptions options = ForwardOptions::PreserveInfo;
|
||||
|
|
|
@ -962,10 +962,12 @@ void RowPainter::Paint(
|
|||
if (!thread) {
|
||||
return nullptr;
|
||||
}
|
||||
if ((!peer || !peer->isForum()) && (!item || !badgesState.unread)) {
|
||||
if ((!peer || (!peer->isForum() && !peer->amMonoforumAdmin()))
|
||||
&& (!item || !badgesState.unread)) {
|
||||
// Draw item, if there are unread messages.
|
||||
const auto draft = thread->owningHistory()->cloudDraft(
|
||||
thread->topicRootId());
|
||||
thread->topicRootId(),
|
||||
thread->monoforumPeerId());
|
||||
if (!Data::DraftIsNull(draft)) {
|
||||
return draft;
|
||||
}
|
||||
|
|
|
@ -206,33 +206,39 @@ void History::itemVanished(not_null<HistoryItem*> item) {
|
|||
|
||||
void History::takeLocalDraft(not_null<History*> from) {
|
||||
const auto topicRootId = MsgId(0);
|
||||
const auto i = from->_drafts.find(Data::DraftKey::Local(topicRootId));
|
||||
const auto monoforumPeerId = PeerId(0);
|
||||
const auto i = from->_drafts.find(
|
||||
Data::DraftKey::Local(topicRootId, monoforumPeerId));
|
||||
if (i == end(from->_drafts)) {
|
||||
return;
|
||||
}
|
||||
auto &draft = i->second;
|
||||
if (!draft->textWithTags.text.isEmpty()
|
||||
&& !_drafts.contains(Data::DraftKey::Local(topicRootId))) {
|
||||
&& !_drafts.contains(
|
||||
Data::DraftKey::Local(topicRootId, monoforumPeerId))) {
|
||||
// Edit and reply to drafts can't migrate.
|
||||
// Cloud drafts do not migrate automatically.
|
||||
draft->reply = FullReplyTo();
|
||||
setLocalDraft(std::move(draft));
|
||||
}
|
||||
from->clearLocalDraft(topicRootId);
|
||||
from->clearLocalDraft(topicRootId, monoforumPeerId);
|
||||
session().api().saveDraftToCloudDelayed(from);
|
||||
}
|
||||
|
||||
void History::createLocalDraftFromCloud(MsgId topicRootId) {
|
||||
const auto draft = cloudDraft(topicRootId);
|
||||
void History::createLocalDraftFromCloud(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
const auto draft = cloudDraft(topicRootId, monoforumPeerId);
|
||||
if (!draft) {
|
||||
clearLocalDraft(topicRootId);
|
||||
clearLocalDraft(topicRootId, monoforumPeerId);
|
||||
return;
|
||||
} else if (Data::DraftIsNull(draft) || !draft->date) {
|
||||
return;
|
||||
}
|
||||
|
||||
draft->reply.topicRootId = topicRootId;
|
||||
auto existing = localDraft(topicRootId);
|
||||
draft->reply.monoforumPeerId = monoforumPeerId;
|
||||
auto existing = localDraft(topicRootId, monoforumPeerId);
|
||||
if (Data::DraftIsNull(existing)
|
||||
|| !existing->date
|
||||
|| draft->date >= existing->date) {
|
||||
|
@ -242,7 +248,7 @@ void History::createLocalDraftFromCloud(MsgId topicRootId) {
|
|||
draft->reply,
|
||||
draft->cursor,
|
||||
draft->webpage));
|
||||
existing = localDraft(topicRootId);
|
||||
existing = localDraft(topicRootId, monoforumPeerId);
|
||||
} else if (existing != draft) {
|
||||
existing->textWithTags = draft->textWithTags;
|
||||
existing->reply = draft->reply;
|
||||
|
@ -268,7 +274,7 @@ void History::setDraft(
|
|||
return;
|
||||
}
|
||||
const auto cloudThread = key.isCloud()
|
||||
? threadFor(key.topicRootId())
|
||||
? threadFor(key.topicRootId(), key.monoforumPeerId())
|
||||
: nullptr;
|
||||
if (cloudThread) {
|
||||
cloudThread->cloudDraftTextCache().clear();
|
||||
|
@ -298,7 +304,7 @@ void History::clearDraft(Data::DraftKey key) {
|
|||
void History::clearDrafts() {
|
||||
for (auto &[key, draft] : base::take(_drafts)) {
|
||||
const auto cloudThread = key.isCloud()
|
||||
? threadFor(key.topicRootId())
|
||||
? threadFor(key.topicRootId(), key.monoforumPeerId())
|
||||
: nullptr;
|
||||
if (cloudThread) {
|
||||
cloudThread->cloudDraftTextCache().clear();
|
||||
|
@ -309,25 +315,30 @@ void History::clearDrafts() {
|
|||
|
||||
Data::Draft *History::createCloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
const Data::Draft *fromDraft) {
|
||||
if (Data::DraftIsNull(fromDraft)) {
|
||||
setCloudDraft(std::make_unique<Data::Draft>(
|
||||
TextWithTags(),
|
||||
FullReplyTo{ .topicRootId = topicRootId },
|
||||
FullReplyTo{
|
||||
.topicRootId = topicRootId,
|
||||
.monoforumPeerId = monoforumPeerId,
|
||||
},
|
||||
MessageCursor(),
|
||||
Data::WebPageDraft()));
|
||||
cloudDraft(topicRootId)->date = TimeId(0);
|
||||
cloudDraft(topicRootId, monoforumPeerId)->date = TimeId(0);
|
||||
} else {
|
||||
auto existing = cloudDraft(topicRootId);
|
||||
auto existing = cloudDraft(topicRootId, monoforumPeerId);
|
||||
if (!existing) {
|
||||
auto reply = fromDraft->reply;
|
||||
reply.topicRootId = topicRootId;
|
||||
reply.monoforumPeerId = monoforumPeerId;
|
||||
setCloudDraft(std::make_unique<Data::Draft>(
|
||||
fromDraft->textWithTags,
|
||||
reply,
|
||||
fromDraft->cursor,
|
||||
fromDraft->webpage));
|
||||
existing = cloudDraft(topicRootId);
|
||||
existing = cloudDraft(topicRootId, monoforumPeerId);
|
||||
} else if (existing != fromDraft) {
|
||||
existing->textWithTags = fromDraft->textWithTags;
|
||||
existing->reply = fromDraft->reply;
|
||||
|
@ -336,44 +347,56 @@ Data::Draft *History::createCloudDraft(
|
|||
}
|
||||
existing->date = base::unixtime::now();
|
||||
existing->reply.topicRootId = topicRootId;
|
||||
existing->reply.monoforumPeerId = monoforumPeerId;
|
||||
}
|
||||
|
||||
if (const auto thread = threadFor(topicRootId)) {
|
||||
if (const auto thread = threadFor(topicRootId, monoforumPeerId)) {
|
||||
thread->cloudDraftTextCache().clear();
|
||||
thread->updateChatListSortPosition();
|
||||
}
|
||||
|
||||
return cloudDraft(topicRootId);
|
||||
return cloudDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
|
||||
bool History::skipCloudDraftUpdate(MsgId topicRootId, TimeId date) const {
|
||||
const auto i = _acceptCloudDraftsAfter.find(topicRootId);
|
||||
return _savingCloudDraftRequests.contains(topicRootId)
|
||||
bool History::skipCloudDraftUpdate(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
TimeId date) const {
|
||||
const auto key = Data::DraftKey::Local(topicRootId, monoforumPeerId);
|
||||
const auto i = _acceptCloudDraftsAfter.find(key);
|
||||
return _savingCloudDraftRequests.contains(key)
|
||||
|| (i != _acceptCloudDraftsAfter.end() && date < i->second);
|
||||
}
|
||||
|
||||
void History::startSavingCloudDraft(MsgId topicRootId) {
|
||||
++_savingCloudDraftRequests[topicRootId];
|
||||
void History::startSavingCloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
const auto key = Data::DraftKey::Local(topicRootId, monoforumPeerId);
|
||||
++_savingCloudDraftRequests[key];
|
||||
}
|
||||
|
||||
void History::finishSavingCloudDraft(MsgId topicRootId, TimeId savedAt) {
|
||||
const auto i = _savingCloudDraftRequests.find(topicRootId);
|
||||
void History::finishSavingCloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
TimeId savedAt) {
|
||||
const auto key = Data::DraftKey::Local(topicRootId, monoforumPeerId);
|
||||
const auto i = _savingCloudDraftRequests.find(key);
|
||||
if (i != _savingCloudDraftRequests.end()) {
|
||||
if (--i->second <= 0) {
|
||||
_savingCloudDraftRequests.erase(i);
|
||||
}
|
||||
}
|
||||
auto &after = _acceptCloudDraftsAfter[topicRootId];
|
||||
auto &after = _acceptCloudDraftsAfter[key];
|
||||
after = std::max(after, savedAt + kSkipCloudDraftsFor);
|
||||
}
|
||||
|
||||
void History::applyCloudDraft(MsgId topicRootId) {
|
||||
void History::applyCloudDraft(MsgId topicRootId, PeerId monoforumPeerId) {
|
||||
if (!topicRootId && session().supportMode()) {
|
||||
updateChatListEntry();
|
||||
session().supportHelper().cloudDraftChanged(this);
|
||||
} else {
|
||||
createLocalDraftFromCloud(topicRootId);
|
||||
if (const auto thread = threadFor(topicRootId)) {
|
||||
createLocalDraftFromCloud(topicRootId, monoforumPeerId);
|
||||
if (const auto thread = threadFor(topicRootId, monoforumPeerId)) {
|
||||
thread->updateChatListSortPosition();
|
||||
if (!topicRootId) {
|
||||
session().changes().historyUpdated(
|
||||
|
@ -388,17 +411,19 @@ void History::applyCloudDraft(MsgId topicRootId) {
|
|||
}
|
||||
}
|
||||
|
||||
void History::draftSavedToCloud(MsgId topicRootId) {
|
||||
if (const auto thread = threadFor(topicRootId)) {
|
||||
void History::draftSavedToCloud(MsgId topicRootId, PeerId monoforumPeerId) {
|
||||
if (const auto thread = threadFor(topicRootId, monoforumPeerId)) {
|
||||
thread->updateChatListEntry();
|
||||
}
|
||||
session().local().writeDrafts(this);
|
||||
}
|
||||
|
||||
const Data::ForwardDraft &History::forwardDraft(
|
||||
MsgId topicRootId) const {
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const {
|
||||
const auto key = Data::DraftKey::Local(topicRootId, monoforumPeerId);
|
||||
static const auto kEmpty = Data::ForwardDraft();
|
||||
const auto i = _forwardDrafts.find(topicRootId);
|
||||
const auto i = _forwardDrafts.find(key);
|
||||
return (i != end(_forwardDrafts)) ? i->second : kEmpty;
|
||||
}
|
||||
|
||||
|
@ -411,11 +436,12 @@ Data::ResolvedForwardDraft History::resolveForwardDraft(
|
|||
}
|
||||
|
||||
Data::ResolvedForwardDraft History::resolveForwardDraft(
|
||||
MsgId topicRootId) {
|
||||
const auto &draft = forwardDraft(topicRootId);
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
const auto &draft = forwardDraft(topicRootId, monoforumPeerId);
|
||||
auto result = resolveForwardDraft(draft);
|
||||
if (result.items.size() != draft.ids.size()) {
|
||||
setForwardDraft(topicRootId, {
|
||||
setForwardDraft(topicRootId, monoforumPeerId, {
|
||||
.ids = owner().itemsToIds(result.items),
|
||||
.options = result.options,
|
||||
});
|
||||
|
@ -425,24 +451,23 @@ Data::ResolvedForwardDraft History::resolveForwardDraft(
|
|||
|
||||
void History::setForwardDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
Data::ForwardDraft &&draft) {
|
||||
auto changed = false;
|
||||
const auto key = Data::DraftKey::Local(topicRootId, monoforumPeerId);
|
||||
if (draft.ids.empty()) {
|
||||
changed = _forwardDrafts.remove(topicRootId);
|
||||
changed = _forwardDrafts.remove(key);
|
||||
} else {
|
||||
auto &now = _forwardDrafts[topicRootId];
|
||||
auto &now = _forwardDrafts[key];
|
||||
if (now != draft) {
|
||||
now = std::move(draft);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
const auto entry = topicRootId
|
||||
? peer->forumTopicFor(topicRootId)
|
||||
: (Dialogs::Entry*)this;
|
||||
if (entry) {
|
||||
if (const auto thread = threadFor(topicRootId, monoforumPeerId)) {
|
||||
session().changes().entryUpdated(
|
||||
entry,
|
||||
thread,
|
||||
Data::EntryUpdate::Flag::ForwardDraft);
|
||||
}
|
||||
}
|
||||
|
@ -2081,7 +2106,7 @@ void History::applyPinnedUpdate(const MTPDupdateDialogPinned &data) {
|
|||
|
||||
TimeId History::adjustedChatListTimeId() const {
|
||||
const auto result = chatListTimeId();
|
||||
if (const auto draft = cloudDraft(MsgId(0))) {
|
||||
if (const auto draft = cloudDraft(MsgId(), PeerId())) {
|
||||
if (!peer->forum()
|
||||
&& !Data::DraftIsNull(draft)
|
||||
&& !session().supportMode()) {
|
||||
|
@ -2871,7 +2896,8 @@ void History::applyDialog(
|
|||
Data::ApplyPeerCloudDraft(
|
||||
&session(),
|
||||
peer->id,
|
||||
MsgId(0), // topicRootId
|
||||
MsgId(), // topicRootId
|
||||
PeerId(), // monoforumPeerId
|
||||
draft->c_draftMessage());
|
||||
}
|
||||
if (const auto ttl = data.vttl_period()) {
|
||||
|
@ -3101,14 +3127,22 @@ void History::forceFullResize() {
|
|||
_flags |= Flag::HasPendingResizedItems;
|
||||
}
|
||||
|
||||
Data::Thread *History::threadFor(MsgId topicRootId) {
|
||||
Data::Thread *History::threadFor(MsgId topicRootId, PeerId monoforumPeerId) {
|
||||
return topicRootId
|
||||
? peer->forumTopicFor(topicRootId)
|
||||
: static_cast<Data::Thread*>(this);
|
||||
: !monoforumPeerId
|
||||
? static_cast<Data::Thread*>(this)
|
||||
: peer->monoforum()
|
||||
? peer->monoforum()->sublistLoaded(owner().peer(monoforumPeerId))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
const Data::Thread *History::threadFor(MsgId topicRootId) const {
|
||||
return const_cast<History*>(this)->threadFor(topicRootId);
|
||||
const Data::Thread *History::threadFor(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const {
|
||||
return const_cast<History*>(this)->threadFor(
|
||||
topicRootId,
|
||||
monoforumPeerId);
|
||||
}
|
||||
|
||||
void History::forumChanged(Data::Forum *old) {
|
||||
|
@ -3137,7 +3171,7 @@ void History::forumChanged(Data::Forum *old) {
|
|||
} else {
|
||||
_flags &= ~Flag::IsForum;
|
||||
}
|
||||
if (cloudDraft(MsgId(0))) {
|
||||
if (cloudDraft(MsgId(), PeerId())) {
|
||||
updateChatListSortPosition();
|
||||
}
|
||||
_flags |= Flag::PendingAllItemsResize;
|
||||
|
@ -3173,7 +3207,7 @@ void History::monoforumChanged(Data::SavedMessages *old) {
|
|||
} else {
|
||||
_flags &= ~Flag::IsMonoforumAdmin;
|
||||
}
|
||||
if (cloudDraft(MsgId(0))) {
|
||||
if (cloudDraft(MsgId(), PeerId())) {
|
||||
updateChatListSortPosition();
|
||||
}
|
||||
_flags |= Flag::PendingAllItemsResize;
|
||||
|
|
|
@ -62,8 +62,12 @@ public:
|
|||
[[nodiscard]] not_null<History*> owningHistory() override {
|
||||
return this;
|
||||
}
|
||||
[[nodiscard]] Data::Thread *threadFor(MsgId topicRootId);
|
||||
[[nodiscard]] const Data::Thread *threadFor(MsgId topicRootId) const;
|
||||
[[nodiscard]] Data::Thread *threadFor(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId);
|
||||
[[nodiscard]] const Data::Thread *threadFor(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const;
|
||||
|
||||
[[nodiscard]] auto delegateMixin() const
|
||||
-> not_null<HistoryMainElementDelegateMixin*> {
|
||||
|
@ -288,60 +292,89 @@ public:
|
|||
[[nodiscard]] const Data::HistoryDrafts &draftsMap() const;
|
||||
void setDraftsMap(Data::HistoryDrafts &&map);
|
||||
|
||||
Data::Draft *localDraft(MsgId topicRootId) const {
|
||||
return draft(Data::DraftKey::Local(topicRootId));
|
||||
Data::Draft *localDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const {
|
||||
return draft(Data::DraftKey::Local(topicRootId, monoforumPeerId));
|
||||
}
|
||||
Data::Draft *localEditDraft(MsgId topicRootId) const {
|
||||
return draft(Data::DraftKey::LocalEdit(topicRootId));
|
||||
Data::Draft *localEditDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const {
|
||||
return draft(
|
||||
Data::DraftKey::LocalEdit(topicRootId, monoforumPeerId));
|
||||
}
|
||||
Data::Draft *cloudDraft(MsgId topicRootId) const {
|
||||
return draft(Data::DraftKey::Cloud(topicRootId));
|
||||
Data::Draft *cloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const {
|
||||
return draft(Data::DraftKey::Cloud(topicRootId, monoforumPeerId));
|
||||
}
|
||||
void setLocalDraft(std::unique_ptr<Data::Draft> &&draft) {
|
||||
setDraft(
|
||||
Data::DraftKey::Local(draft->reply.topicRootId),
|
||||
Data::DraftKey::Local(
|
||||
draft->reply.topicRootId,
|
||||
draft->reply.monoforumPeerId),
|
||||
std::move(draft));
|
||||
}
|
||||
void setLocalEditDraft(std::unique_ptr<Data::Draft> &&draft) {
|
||||
setDraft(
|
||||
Data::DraftKey::LocalEdit(draft->reply.topicRootId),
|
||||
Data::DraftKey::LocalEdit(
|
||||
draft->reply.topicRootId,
|
||||
draft->reply.monoforumPeerId),
|
||||
std::move(draft));
|
||||
}
|
||||
void setCloudDraft(std::unique_ptr<Data::Draft> &&draft) {
|
||||
setDraft(
|
||||
Data::DraftKey::Cloud(draft->reply.topicRootId),
|
||||
Data::DraftKey::Cloud(
|
||||
draft->reply.topicRootId,
|
||||
draft->reply.monoforumPeerId),
|
||||
std::move(draft));
|
||||
}
|
||||
void clearLocalDraft(MsgId topicRootId) {
|
||||
clearDraft(Data::DraftKey::Local(topicRootId));
|
||||
void clearLocalDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
clearDraft(Data::DraftKey::Local(topicRootId, monoforumPeerId));
|
||||
}
|
||||
void clearCloudDraft(MsgId topicRootId) {
|
||||
clearDraft(Data::DraftKey::Cloud(topicRootId));
|
||||
void clearCloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
clearDraft(Data::DraftKey::Cloud(topicRootId, monoforumPeerId));
|
||||
}
|
||||
void clearLocalEditDraft(MsgId topicRootId) {
|
||||
clearDraft(Data::DraftKey::LocalEdit(topicRootId));
|
||||
void clearLocalEditDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) {
|
||||
clearDraft(Data::DraftKey::LocalEdit(topicRootId, monoforumPeerId));
|
||||
}
|
||||
void clearDrafts();
|
||||
Data::Draft *createCloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
const Data::Draft *fromDraft);
|
||||
[[nodiscard]] bool skipCloudDraftUpdate(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
TimeId date) const;
|
||||
void startSavingCloudDraft(MsgId topicRootId);
|
||||
void finishSavingCloudDraft(MsgId topicRootId, TimeId savedAt);
|
||||
void startSavingCloudDraft(MsgId topicRootId, PeerId monoforumPeerId);
|
||||
void finishSavingCloudDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
TimeId savedAt);
|
||||
void takeLocalDraft(not_null<History*> from);
|
||||
void applyCloudDraft(MsgId topicRootId);
|
||||
void draftSavedToCloud(MsgId topicRootId);
|
||||
void applyCloudDraft(MsgId topicRootId, PeerId monoforumPeerId);
|
||||
void draftSavedToCloud(MsgId topicRootId, PeerId monoforumPeerId);
|
||||
void requestChatListMessage();
|
||||
|
||||
[[nodiscard]] const Data::ForwardDraft &forwardDraft(
|
||||
MsgId topicRootId) const;
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId) const;
|
||||
[[nodiscard]] Data::ResolvedForwardDraft resolveForwardDraft(
|
||||
const Data::ForwardDraft &draft) const;
|
||||
[[nodiscard]] Data::ResolvedForwardDraft resolveForwardDraft(
|
||||
MsgId topicRootId);
|
||||
void setForwardDraft(MsgId topicRootId, Data::ForwardDraft &&draft);
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId);
|
||||
void setForwardDraft(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
Data::ForwardDraft &&draft);
|
||||
|
||||
History *migrateSibling() const;
|
||||
[[nodiscard]] bool useTopPromotion() const;
|
||||
|
@ -548,7 +581,9 @@ private:
|
|||
|
||||
void viewReplaced(not_null<const Element*> was, Element *now);
|
||||
|
||||
void createLocalDraftFromCloud(MsgId topicRootId);
|
||||
void createLocalDraftFromCloud(
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId);
|
||||
|
||||
HistoryItem *insertJoinedMessage();
|
||||
void insertMessageToBlocks(not_null<HistoryItem*> item);
|
||||
|
@ -606,9 +641,9 @@ private:
|
|||
std::unique_ptr<HistoryTranslation> _translation;
|
||||
|
||||
Data::HistoryDrafts _drafts;
|
||||
base::flat_map<MsgId, TimeId> _acceptCloudDraftsAfter;
|
||||
base::flat_map<MsgId, int> _savingCloudDraftRequests;
|
||||
Data::ForwardDrafts _forwardDrafts;
|
||||
base::flat_map<Data::DraftKey, TimeId> _acceptCloudDraftsAfter;
|
||||
base::flat_map<Data::DraftKey, int> _savingCloudDraftRequests;
|
||||
base::flat_map<Data::DraftKey, Data::ForwardDraft> _forwardDrafts;
|
||||
|
||||
QString _topPromotedMessage;
|
||||
QString _topPromotedType;
|
||||
|
|
|
@ -1118,7 +1118,7 @@ void HistoryWidget::initVoiceRecordBar() {
|
|||
});
|
||||
|
||||
const auto applyLocalDraft = [=] {
|
||||
if (_history && _history->localDraft({})) {
|
||||
if (_history && _history->localDraft(MsgId(), PeerId())) {
|
||||
applyDraft();
|
||||
}
|
||||
};
|
||||
|
@ -1874,12 +1874,14 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
|||
}
|
||||
|
||||
const auto topicRootId = MsgId();
|
||||
const auto monoforumPeerId = PeerId();
|
||||
if (_editMsgId) {
|
||||
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
||||
_field,
|
||||
FullReplyTo{
|
||||
.messageId = FullMsgId(_history->peer->id, _editMsgId),
|
||||
.topicRootId = topicRootId,
|
||||
.monoforumPeerId = monoforumPeerId,
|
||||
},
|
||||
_preview->draft(),
|
||||
_saveEditMsgRequestId));
|
||||
|
@ -1890,9 +1892,9 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
|||
_replyTo,
|
||||
_preview->draft()));
|
||||
} else {
|
||||
_history->clearLocalDraft(topicRootId);
|
||||
_history->clearLocalDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
_history->clearLocalEditDraft(topicRootId);
|
||||
_history->clearLocalEditDraft(topicRootId, monoforumPeerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2187,11 +2189,13 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
}
|
||||
});
|
||||
|
||||
const auto editDraft = _history ? _history->localEditDraft({}) : nullptr;
|
||||
const auto editDraft = _history
|
||||
? _history->localEditDraft(MsgId(), PeerId())
|
||||
: nullptr;
|
||||
const auto draft = editDraft
|
||||
? editDraft
|
||||
: _history
|
||||
? _history->localDraft({})
|
||||
? _history->localDraft(MsgId(), PeerId())
|
||||
: nullptr;
|
||||
auto fieldAvailable = canWriteMessage();
|
||||
const auto editMsgId = editDraft ? editDraft->reply.messageId.msg : 0;
|
||||
|
@ -2241,7 +2245,7 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
requestMessageData(_editMsgId);
|
||||
}
|
||||
} else {
|
||||
const auto draft = _history->localDraft({});
|
||||
const auto draft = _history->localDraft(MsgId(), PeerId());
|
||||
_processingReplyTo = draft ? draft->reply : FullReplyTo();
|
||||
if (_processingReplyTo) {
|
||||
_processingReplyItem = session().data().message(
|
||||
|
@ -2408,7 +2412,7 @@ void HistoryWidget::showHistory(
|
|||
info->inlineReturnTo = wasState;
|
||||
}
|
||||
sendBotStartCommand();
|
||||
_history->clearLocalDraft({});
|
||||
_history->clearLocalDraft(MsgId(), PeerId());
|
||||
applyDraft();
|
||||
_send->finishAnimating();
|
||||
}
|
||||
|
@ -2864,10 +2868,10 @@ void HistoryWidget::unregisterDraftSources() {
|
|||
}
|
||||
session().local().unregisterDraftSource(
|
||||
_history,
|
||||
Data::DraftKey::Local({}));
|
||||
Data::DraftKey::Local(MsgId(), PeerId()));
|
||||
session().local().unregisterDraftSource(
|
||||
_history,
|
||||
Data::DraftKey::LocalEdit({}));
|
||||
Data::DraftKey::LocalEdit(MsgId(), PeerId()));
|
||||
}
|
||||
|
||||
void HistoryWidget::registerDraftSource() {
|
||||
|
@ -2892,8 +2896,8 @@ void HistoryWidget::registerDraftSource() {
|
|||
session().local().registerDraftSource(
|
||||
_history,
|
||||
(editMsgId
|
||||
? Data::DraftKey::LocalEdit({})
|
||||
: Data::DraftKey::Local({})),
|
||||
? Data::DraftKey::LocalEdit(MsgId(), PeerId())
|
||||
: Data::DraftKey::Local(MsgId(), PeerId())),
|
||||
std::move(draftSource));
|
||||
}
|
||||
|
||||
|
@ -3630,6 +3634,7 @@ void HistoryWidget::unreadCountUpdated() {
|
|||
});
|
||||
} else {
|
||||
const auto hideCounter = _history->isForum()
|
||||
|| _history->amMonoforumAdmin()
|
||||
|| !_history->trackUnreadMessages();
|
||||
_cornerButtons.updateJumpDownVisibility(hideCounter
|
||||
? 0
|
||||
|
@ -4376,16 +4381,16 @@ void HistoryWidget::saveEditMsg() {
|
|||
cancelEdit();
|
||||
}
|
||||
})();
|
||||
if (const auto editDraft = history->localEditDraft({})) {
|
||||
if (const auto editDraft = history->localEditDraft({}, {})) {
|
||||
if (editDraft->saveRequestId == requestId) {
|
||||
history->clearLocalEditDraft({});
|
||||
history->clearLocalEditDraft(MsgId(), PeerId());
|
||||
history->session().local().writeDrafts(history);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const auto fail = [=](const QString &error, mtpRequestId requestId) {
|
||||
if (const auto editDraft = history->localEditDraft({})) {
|
||||
if (const auto editDraft = history->localEditDraft({}, {})) {
|
||||
if (editDraft->saveRequestId == requestId) {
|
||||
editDraft->saveRequestId = 0;
|
||||
}
|
||||
|
@ -7276,7 +7281,7 @@ void HistoryWidget::editDraftOptions() {
|
|||
} else {
|
||||
cancelReply();
|
||||
}
|
||||
history->setForwardDraft({}, std::move(forward));
|
||||
history->setForwardDraft(MsgId(), PeerId(), std::move(forward));
|
||||
_preview->apply(webpage);
|
||||
};
|
||||
const auto replyToId = reply.messageId;
|
||||
|
@ -7295,7 +7300,9 @@ void HistoryWidget::editDraftOptions() {
|
|||
.resolver = _preview->resolver(),
|
||||
.done = done,
|
||||
.highlight = highlight,
|
||||
.clearOldDraft = [=] { ClearDraftReplyTo(history, 0, replyToId); },
|
||||
.clearOldDraft = [=] {
|
||||
ClearDraftReplyTo(history, MsgId(), PeerId(), replyToId);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -8418,7 +8425,7 @@ void HistoryWidget::setReplyFieldsFromProcessing() {
|
|||
const auto id = base::take(_processingReplyTo);
|
||||
const auto item = base::take(_processingReplyItem);
|
||||
if (_editMsgId) {
|
||||
if (const auto localDraft = _history->localDraft({})) {
|
||||
if (const auto localDraft = _history->localDraft({}, {})) {
|
||||
localDraft->reply = id;
|
||||
} else {
|
||||
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
|
@ -8470,7 +8477,7 @@ void HistoryWidget::editMessage(
|
|||
_replyTo,
|
||||
_preview->draft()));
|
||||
} else {
|
||||
_history->clearLocalDraft({});
|
||||
_history->clearLocalDraft(MsgId(), PeerId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8580,10 +8587,10 @@ bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
|||
updateControlsGeometry();
|
||||
update();
|
||||
} else if (const auto localDraft
|
||||
= (_history ? _history->localDraft({}) : nullptr)) {
|
||||
= (_history ? _history->localDraft({}, {}) : nullptr)) {
|
||||
if (localDraft->reply) {
|
||||
if (localDraft->textWithTags.text.isEmpty()) {
|
||||
_history->clearLocalDraft({});
|
||||
_history->clearLocalDraft(MsgId(), PeerId());
|
||||
} else {
|
||||
localDraft->reply = {};
|
||||
}
|
||||
|
@ -8629,7 +8636,7 @@ void HistoryWidget::cancelEdit() {
|
|||
updateReplaceMediaButton();
|
||||
_replyEditMsg = nullptr;
|
||||
setEditMsgId(0);
|
||||
_history->clearLocalEditDraft({});
|
||||
_history->clearLocalEditDraft(MsgId(), PeerId());
|
||||
applyDraft();
|
||||
|
||||
if (_saveEditMsgRequestId) {
|
||||
|
@ -8671,7 +8678,7 @@ void HistoryWidget::cancelFieldAreaState() {
|
|||
} else if (_replyTo) {
|
||||
cancelReply();
|
||||
} else if (readyToForward()) {
|
||||
_history->setForwardDraft(MsgId(), {});
|
||||
_history->setForwardDraft(MsgId(), PeerId(), {});
|
||||
} else if (_kbReplyTo) {
|
||||
toggleKeyboard();
|
||||
}
|
||||
|
@ -9039,7 +9046,7 @@ void HistoryWidget::updateReplyEditTexts(bool force) {
|
|||
|
||||
void HistoryWidget::updateForwarding() {
|
||||
_forwardPanel->update(_history, _history
|
||||
? _history->resolveForwardDraft(MsgId())
|
||||
? _history->resolveForwardDraft(MsgId(), PeerId())
|
||||
: Data::ResolvedForwardDraft());
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
|
|
|
@ -66,6 +66,7 @@ struct WriteRestriction {
|
|||
struct SetHistoryArgs {
|
||||
required<History*> history;
|
||||
MsgId topicRootId = 0;
|
||||
PeerId monoforumPeerId = 0;
|
||||
Fn<bool()> showSlowmodeError;
|
||||
Fn<Api::SendAction()> sendActionFactory;
|
||||
rpl::producer<int> slowmodeSecondsLeft;
|
||||
|
|
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_changes.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_messages.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_chat.h"
|
||||
|
@ -197,6 +198,7 @@ private:
|
|||
|
||||
History *_history = nullptr;
|
||||
MsgId _topicRootId = 0;
|
||||
PeerId _monoforumPeerId = 0;
|
||||
|
||||
Preview _preview;
|
||||
rpl::event_stream<> _editCancelled;
|
||||
|
@ -254,6 +256,7 @@ FieldHeader::FieldHeader(
|
|||
void FieldHeader::setHistory(const SetHistoryArgs &args) {
|
||||
_history = *args.history;
|
||||
_topicRootId = args.topicRootId;
|
||||
_monoforumPeerId = args.monoforumPeerId;
|
||||
}
|
||||
|
||||
void FieldHeader::updateTopicRootId(MsgId topicRootId) {
|
||||
|
@ -282,7 +285,7 @@ void FieldHeader::init() {
|
|||
st::historyLinkIcon.paint(p, position, width());
|
||||
} else if (isEditingMessage()) {
|
||||
st::historyEditIcon.paint(p, position, width());
|
||||
} else if (const auto reply = replyingToMessage()) {
|
||||
} else if (const auto reply = replyingToMessage(); reply.replying()) {
|
||||
if (!reply.quote.empty()) {
|
||||
st::historyQuoteIcon.paint(p, position, width());
|
||||
} else {
|
||||
|
@ -760,6 +763,7 @@ void FieldHeader::editMessage(FullMsgId id, bool photoEditAllowed) {
|
|||
}
|
||||
|
||||
void FieldHeader::replyToMessage(FullReplyTo id) {
|
||||
id.monoforumPeerId = 0;
|
||||
_replyTo = id;
|
||||
}
|
||||
|
||||
|
@ -956,6 +960,7 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
|
|||
unregisterDraftSources();
|
||||
_history = history;
|
||||
_topicRootId = args.topicRootId;
|
||||
_monoforumPeerId = args.monoforumPeerId;
|
||||
_historyLifetime.destroy();
|
||||
_header->setHistory(args);
|
||||
registerDraftSource();
|
||||
|
@ -999,6 +1004,7 @@ void ComposeControls::setCurrentDialogsEntryState(
|
|||
Dialogs::EntryState state) {
|
||||
unregisterDraftSources();
|
||||
state.currentReplyTo.topicRootId = _topicRootId;
|
||||
state.currentReplyTo.monoforumPeerId = _monoforumPeerId;
|
||||
_currentDialogsEntryState = state;
|
||||
updateForwarding();
|
||||
registerDraftSource();
|
||||
|
@ -1405,6 +1411,7 @@ void ComposeControls::init() {
|
|||
) | rpl::start_with_next([=] {
|
||||
const auto history = _history;
|
||||
const auto topicRootId = _topicRootId;
|
||||
const auto monoforumPeerId = _monoforumPeerId;
|
||||
const auto reply = _header->replyingToMessage();
|
||||
const auto webpage = _preview->draft();
|
||||
|
||||
|
@ -1417,7 +1424,10 @@ void ComposeControls::init() {
|
|||
} else {
|
||||
cancelReplyMessage();
|
||||
}
|
||||
history->setForwardDraft(topicRootId, std::move(forward));
|
||||
history->setForwardDraft(
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
std::move(forward));
|
||||
_preview->apply(webpage);
|
||||
_field->setFocus();
|
||||
};
|
||||
|
@ -1440,6 +1450,7 @@ void ComposeControls::init() {
|
|||
.clearOldDraft = [=] { ClearDraftReplyTo(
|
||||
history,
|
||||
topicRootId,
|
||||
monoforumPeerId,
|
||||
replyToId); },
|
||||
});
|
||||
}, _wrap->lifetime());
|
||||
|
@ -1809,8 +1820,8 @@ Data::DraftKey ComposeControls::draftKey(DraftType type) const {
|
|||
case Section::Replies:
|
||||
case Section::SavedSublist:
|
||||
return (type == DraftType::Edit)
|
||||
? Key::LocalEdit(_topicRootId)
|
||||
: Key::Local(_topicRootId);
|
||||
? Key::LocalEdit(_topicRootId, _monoforumPeerId)
|
||||
: Key::Local(_topicRootId, _monoforumPeerId);
|
||||
case Section::Scheduled:
|
||||
return (type == DraftType::Edit)
|
||||
? Key::ScheduledEdit()
|
||||
|
@ -2038,7 +2049,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
}
|
||||
|
||||
void ComposeControls::cancelForward() {
|
||||
_history->setForwardDraft(_topicRootId, {});
|
||||
_history->setForwardDraft(_topicRootId, _monoforumPeerId, {});
|
||||
updateForwarding();
|
||||
}
|
||||
|
||||
|
@ -2902,9 +2913,11 @@ void ComposeControls::toggleTabbedSelectorMode() {
|
|||
&& !_regularWindow->adaptive().isOneColumn()) {
|
||||
Core::App().settings().setTabbedSelectorSectionEnabled(true);
|
||||
Core::App().saveSettingsDelayed();
|
||||
const auto topic = _history->peer->forumTopicFor(_topicRootId);
|
||||
const auto thread = _history->threadFor(
|
||||
_topicRootId,
|
||||
_monoforumPeerId);
|
||||
pushTabbedSelectorToThirdSection(
|
||||
(topic ? topic : (Data::Thread*)_history),
|
||||
thread ? thread : _history,
|
||||
Window::SectionShow::Way::ClearStack);
|
||||
} else {
|
||||
_tabbedPanel->toggleAnimated();
|
||||
|
@ -2958,6 +2971,7 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
|||
FullReplyTo{
|
||||
.messageId = item->fullId(),
|
||||
.topicRootId = key.topicRootId(),
|
||||
.monoforumPeerId = key.monoforumPeerId(),
|
||||
},
|
||||
cursor,
|
||||
Data::WebPageDraft::FromItem(item)));
|
||||
|
@ -3038,6 +3052,7 @@ void ComposeControls::replyToMessage(FullReplyTo id) {
|
|||
Expects(draftKeyCurrent() != Data::DraftKey::None());
|
||||
|
||||
id.topicRootId = _topicRootId;
|
||||
id.monoforumPeerId = _monoforumPeerId;
|
||||
if (!id) {
|
||||
cancelReplyMessage();
|
||||
return;
|
||||
|
@ -3045,6 +3060,7 @@ void ComposeControls::replyToMessage(FullReplyTo id) {
|
|||
if (isEditingMessage()) {
|
||||
const auto key = draftKey(DraftType::Normal);
|
||||
Assert(key.topicRootId() == id.topicRootId);
|
||||
Assert(key.monoforumPeerId() == id.monoforumPeerId);
|
||||
if (const auto localDraft = _history->draft(key)) {
|
||||
localDraft->reply = id;
|
||||
} else {
|
||||
|
@ -3088,12 +3104,11 @@ void ComposeControls::cancelReplyMessage() {
|
|||
}
|
||||
|
||||
void ComposeControls::updateForwarding() {
|
||||
const auto rootId = _topicRootId;
|
||||
const auto thread = (_history && rootId)
|
||||
? _history->peer->forumTopicFor(rootId)
|
||||
const auto thread = (_history && (_topicRootId || _monoforumPeerId))
|
||||
? _history->threadFor(_topicRootId, _monoforumPeerId)
|
||||
: (Data::Thread*)_history;
|
||||
_header->updateForwarding(thread, thread
|
||||
? _history->resolveForwardDraft(rootId)
|
||||
? _history->resolveForwardDraft(_topicRootId, _monoforumPeerId)
|
||||
: Data::ResolvedForwardDraft());
|
||||
updateSendButtonType();
|
||||
}
|
||||
|
@ -3108,7 +3123,7 @@ bool ComposeControls::handleCancelRequest() {
|
|||
} else if (isEditingMessage()) {
|
||||
maybeCancelEditMessage();
|
||||
return true;
|
||||
} else if (replyingToMessage()) {
|
||||
} else if (replyingToMessage().replying()) {
|
||||
cancelReplyMessage();
|
||||
return true;
|
||||
} else if (readyToForward()) {
|
||||
|
@ -3186,6 +3201,11 @@ void ComposeControls::initForwardProcess() {
|
|||
&& topic->rootId() == _topicRootId) {
|
||||
updateForwarding();
|
||||
}
|
||||
} else if (const auto sublist = update.entry->asSublist()) {
|
||||
if (sublist->owningHistory() == _history
|
||||
&& sublist->sublistPeer()->id == _monoforumPeerId) {
|
||||
updateForwarding();
|
||||
}
|
||||
}
|
||||
}, _wrap->lifetime());
|
||||
|
||||
|
@ -3209,6 +3229,7 @@ bool ComposeControls::isEditingMessage() const {
|
|||
FullReplyTo ComposeControls::replyingToMessage() const {
|
||||
auto result = _header->replyingToMessage();
|
||||
result.topicRootId = _topicRootId;
|
||||
result.monoforumPeerId = _monoforumPeerId;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -365,6 +365,7 @@ private:
|
|||
|
||||
History *_history = nullptr;
|
||||
MsgId _topicRootId = 0;
|
||||
PeerId _monoforumPeerId = 0;
|
||||
BusinessShortcutId _shortcutId = 0;
|
||||
Fn<bool()> _showSlowmodeError;
|
||||
Fn<Api::SendAction()> _sendActionFactory;
|
||||
|
|
|
@ -1375,18 +1375,20 @@ void ShowReplyToChatBox(
|
|||
auto chosen = [=](not_null<Data::Thread*> thread) mutable {
|
||||
const auto history = thread->owningHistory();
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
const auto draft = history->localDraft(topicRootId);
|
||||
const auto monoforumPeerId = thread->monoforumPeerId();
|
||||
const auto draft = history->localDraft(topicRootId, monoforumPeerId);
|
||||
const auto textWithTags = draft
|
||||
? draft->textWithTags
|
||||
: TextWithTags();
|
||||
const auto cursor = draft ? draft->cursor : MessageCursor();
|
||||
reply.topicRootId = topicRootId;
|
||||
reply.monoforumPeerId = monoforumPeerId;
|
||||
history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
textWithTags,
|
||||
reply,
|
||||
cursor,
|
||||
Data::WebPageDraft()));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->clearLocalEditDraft(topicRootId, monoforumPeerId);
|
||||
history->session().changes().entryUpdated(
|
||||
thread,
|
||||
Data::EntryUpdate::Flag::LocalDraftSet);
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history_item_helpers.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/view/history_view_item_preview.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
|
@ -74,6 +75,11 @@ void ForwardPanel::update(
|
|||
) | rpl::start_with_next([=] {
|
||||
update(nullptr, {});
|
||||
}, _dataLifetime);
|
||||
} else if (const auto sublist = _to->asSublist()) {
|
||||
sublist->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
update(nullptr, {});
|
||||
}, _dataLifetime);
|
||||
}
|
||||
|
||||
updateTexts();
|
||||
|
@ -231,8 +237,10 @@ void ForwardPanel::applyOptions(Data::ForwardOptions options) {
|
|||
if (_data.items.empty()) {
|
||||
return;
|
||||
} else if (_data.options != options) {
|
||||
const auto topicRootId = _to->topicRootId();
|
||||
const auto monoforumPeerId = _to->monoforumPeerId();
|
||||
_data.options = options;
|
||||
_to->owningHistory()->setForwardDraft(_to->topicRootId(), {
|
||||
_to->owningHistory()->setForwardDraft(topicRootId, monoforumPeerId, {
|
||||
.ids = _to->owner().itemsToIds(_data.items),
|
||||
.options = options,
|
||||
});
|
||||
|
@ -256,7 +264,9 @@ void ForwardPanel::editToNextOption() {
|
|||
? Options::NoNamesAndCaptions
|
||||
: Options::PreserveInfo;
|
||||
|
||||
_to->owningHistory()->setForwardDraft(_to->topicRootId(), {
|
||||
const auto topicRootId = _to->topicRootId();
|
||||
const auto monoforumPeerId = _to->monoforumPeerId();
|
||||
_to->owningHistory()->setForwardDraft(topicRootId, monoforumPeerId, {
|
||||
.ids = _to->owner().itemsToIds(_data.items),
|
||||
.options = next,
|
||||
});
|
||||
|
@ -332,20 +342,25 @@ void ForwardPanel::paint(
|
|||
void ClearDraftReplyTo(
|
||||
not_null<History*> history,
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
FullMsgId equalTo) {
|
||||
const auto local = history->localDraft(topicRootId);
|
||||
const auto local = history->localDraft(topicRootId, monoforumPeerId);
|
||||
if (!local || (equalTo && local->reply.messageId != equalTo)) {
|
||||
return;
|
||||
}
|
||||
auto draft = *local;
|
||||
draft.reply = { .topicRootId = topicRootId };
|
||||
draft.reply = {
|
||||
.topicRootId = topicRootId,
|
||||
.monoforumPeerId = monoforumPeerId,
|
||||
};
|
||||
if (Data::DraftIsNull(&draft)) {
|
||||
history->clearLocalDraft(topicRootId);
|
||||
history->clearLocalDraft(topicRootId, monoforumPeerId);
|
||||
} else {
|
||||
history->setLocalDraft(
|
||||
std::make_unique<Data::Draft>(std::move(draft)));
|
||||
}
|
||||
if (const auto thread = history->threadFor(topicRootId)) {
|
||||
const auto thread = history->threadFor(topicRootId, monoforumPeerId);
|
||||
if (thread) {
|
||||
history->session().api().saveDraftToCloudDelayed(thread);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ private:
|
|||
void ClearDraftReplyTo(
|
||||
not_null<History*> history,
|
||||
MsgId topicRootId,
|
||||
PeerId monoforumPeerId,
|
||||
FullMsgId equalTo);
|
||||
|
||||
void EditWebPageOptions(
|
||||
|
|
|
@ -438,8 +438,10 @@ ChatWidget::ChatWidget(
|
|||
|
||||
ChatWidget::~ChatWidget() {
|
||||
base::take(_sendAction);
|
||||
if (_repliesRootId) {
|
||||
if (_repliesRootId || _sublist) {
|
||||
session().api().saveCurrentDraftToCloud();
|
||||
}
|
||||
if (_repliesRootId) {
|
||||
controller()->sendingAnimation().clear();
|
||||
}
|
||||
if (_topic) {
|
||||
|
@ -747,7 +749,8 @@ void ChatWidget::setupComposeControls() {
|
|||
|
||||
_composeControls->setHistory({
|
||||
.history = _history.get(),
|
||||
.topicRootId = _topic ? _topic->rootId() : MsgId(0),
|
||||
.topicRootId = _topic ? _topic->rootId() : MsgId(),
|
||||
.monoforumPeerId = _sublist ? _sublist->sublistPeer()->id : PeerId(),
|
||||
.showSlowmodeError = [=] { return showSlowmodeError(); },
|
||||
.sendActionFactory = [=] { return prepareSendAction({}); },
|
||||
.slowmodeSecondsLeft = SlowmodeSecondsLeft(_peer),
|
||||
|
|
|
@ -557,6 +557,7 @@ bool MainWidget::setForwardDraft(
|
|||
const auto history = thread->owningHistory();
|
||||
const auto items = session().data().idsToItems(draft.ids);
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
const auto monoforumPeerId = thread->monoforumPeerId();
|
||||
const auto error = GetErrorForSending(
|
||||
history->peer,
|
||||
{
|
||||
|
@ -569,7 +570,7 @@ bool MainWidget::setForwardDraft(
|
|||
return false;
|
||||
}
|
||||
|
||||
history->setForwardDraft(topicRootId, std::move(draft));
|
||||
history->setForwardDraft(topicRootId, monoforumPeerId, std::move(draft));
|
||||
_controller->showThread(
|
||||
thread,
|
||||
ShowAtUnreadMsgId,
|
||||
|
@ -596,12 +597,16 @@ bool MainWidget::shareUrl(
|
|||
};
|
||||
const auto history = thread->owningHistory();
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
const auto monoforumPeerId = thread->monoforumPeerId();
|
||||
history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
textWithTags,
|
||||
FullReplyTo{ .topicRootId = topicRootId },
|
||||
FullReplyTo{
|
||||
.topicRootId = topicRootId,
|
||||
.monoforumPeerId = monoforumPeerId,
|
||||
},
|
||||
cursor,
|
||||
Data::WebPageDraft()));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->clearLocalEditDraft(topicRootId, monoforumPeerId);
|
||||
history->session().changes().entryUpdated(
|
||||
thread,
|
||||
Data::EntryUpdate::Flag::LocalDraftSet);
|
||||
|
@ -2044,6 +2049,8 @@ bool MainWidget::showBackFromStack(const SectionShow ¶ms) {
|
|||
});
|
||||
return (_dialogs != nullptr);
|
||||
}
|
||||
session().api().saveCurrentDraftToCloud();
|
||||
|
||||
auto item = std::move(_stack.back());
|
||||
_stack.pop_back();
|
||||
if (const auto currentHistoryPeer = _history->peer()) {
|
||||
|
|
|
@ -1176,7 +1176,9 @@ void EnumerateDrafts(
|
|||
} else if (key.isLocal()
|
||||
&& (!supportMode || key.topicRootId())) {
|
||||
const auto i = map.find(
|
||||
Data::DraftKey::Cloud(key.topicRootId()));
|
||||
Data::DraftKey::Cloud(
|
||||
key.topicRootId(),
|
||||
key.monoforumPeerId()));
|
||||
const auto cloud = (i != end(map)) ? i->second.get() : nullptr;
|
||||
if (Data::DraftsAreEqual(draft.get(), cloud)) {
|
||||
continue;
|
||||
|
@ -1426,7 +1428,7 @@ void Account::readDraftCursors(PeerId peerId, Data::HistoryDrafts &map) {
|
|||
? Data::DraftKey::FromSerialized(keyValue)
|
||||
: keysOld
|
||||
? Data::DraftKey::FromSerializedOld(keyValueOld)
|
||||
: Data::DraftKey::Local(0);
|
||||
: Data::DraftKey::Local(MsgId(), PeerId());
|
||||
qint32 position = 0, anchor = 0, scroll = Ui::kQFixedMax;
|
||||
draft.stream >> position >> anchor >> scroll;
|
||||
if (const auto i = map.find(key); i != end(map)) {
|
||||
|
@ -1453,13 +1455,14 @@ void Account::readDraftCursorsLegacy(
|
|||
return;
|
||||
}
|
||||
|
||||
if (const auto i = map.find(Data::DraftKey::Local({})); i != end(map)) {
|
||||
if (const auto i = map.find(Data::DraftKey::Local(MsgId(), PeerId()))
|
||||
; i != end(map)) {
|
||||
i->second->cursor = MessageCursor(
|
||||
localPosition,
|
||||
localAnchor,
|
||||
localScroll);
|
||||
}
|
||||
if (const auto i = map.find(Data::DraftKey::LocalEdit({}))
|
||||
if (const auto i = map.find(Data::DraftKey::LocalEdit(MsgId(), PeerId()))
|
||||
; i != end(map)) {
|
||||
i->second->cursor = MessageCursor(
|
||||
editPosition,
|
||||
|
@ -1472,7 +1475,7 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
|||
const auto guard = gsl::finally([&] {
|
||||
if (const auto migrated = history->migrateFrom()) {
|
||||
readDraftsWithCursors(migrated);
|
||||
migrated->clearLocalEditDraft({});
|
||||
migrated->clearLocalEditDraft(MsgId(), PeerId());
|
||||
history->takeLocalDraft(migrated);
|
||||
}
|
||||
});
|
||||
|
@ -1643,10 +1646,11 @@ void Account::readDraftsWithCursorsLegacy(
|
|||
editData.text.size());
|
||||
|
||||
const auto topicRootId = MsgId();
|
||||
const auto monoforumPeerId = PeerId();
|
||||
auto map = base::flat_map<Data::DraftKey, std::unique_ptr<Data::Draft>>();
|
||||
if (!msgData.text.isEmpty() || msgReplyTo) {
|
||||
map.emplace(
|
||||
Data::DraftKey::Local(topicRootId),
|
||||
Data::DraftKey::Local(topicRootId, monoforumPeerId),
|
||||
std::make_unique<Data::Draft>(
|
||||
msgData,
|
||||
FullReplyTo{ FullMsgId(peerId, MsgId(msgReplyTo)) },
|
||||
|
@ -1657,7 +1661,7 @@ void Account::readDraftsWithCursorsLegacy(
|
|||
}
|
||||
if (editMsgId) {
|
||||
map.emplace(
|
||||
Data::DraftKey::LocalEdit(topicRootId),
|
||||
Data::DraftKey::LocalEdit(topicRootId, monoforumPeerId),
|
||||
std::make_unique<Data::Draft>(
|
||||
editData,
|
||||
FullReplyTo{ FullMsgId(peerId, editMsgId) },
|
||||
|
|
|
@ -54,6 +54,7 @@ constexpr auto kOccupyFor = TimeId(60);
|
|||
constexpr auto kReoccupyEach = 30 * crl::time(1000);
|
||||
constexpr auto kMaxSupportInfoLength = MaxMessageSize * 4;
|
||||
constexpr auto kTopicRootId = MsgId(0);
|
||||
constexpr auto kMonoforumPeerId = PeerId(0);
|
||||
|
||||
class EditInfoBox : public Ui::BoxContent {
|
||||
public:
|
||||
|
@ -183,7 +184,7 @@ uint32 ParseOccupationTag(History *history) {
|
|||
if (!TrackHistoryOccupation(history)) {
|
||||
return 0;
|
||||
}
|
||||
const auto draft = history->cloudDraft(kTopicRootId);
|
||||
const auto draft = history->cloudDraft(kTopicRootId, kMonoforumPeerId);
|
||||
if (!draft) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -209,7 +210,7 @@ QString ParseOccupationName(History *history) {
|
|||
if (!TrackHistoryOccupation(history)) {
|
||||
return QString();
|
||||
}
|
||||
const auto draft = history->cloudDraft(kTopicRootId);
|
||||
const auto draft = history->cloudDraft(kTopicRootId, kMonoforumPeerId);
|
||||
if (!draft) {
|
||||
return QString();
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ TimeId OccupiedBySomeoneTill(History *history) {
|
|||
if (!TrackHistoryOccupation(history)) {
|
||||
return 0;
|
||||
}
|
||||
const auto draft = history->cloudDraft(kTopicRootId);
|
||||
const auto draft = history->cloudDraft(kTopicRootId, kMonoforumPeerId);
|
||||
if (!draft) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -353,7 +354,7 @@ void Helper::updateOccupiedHistory(
|
|||
not_null<Window::SessionController*> controller,
|
||||
History *history) {
|
||||
if (isOccupiedByMe(_occupiedHistory)) {
|
||||
_occupiedHistory->clearCloudDraft(kTopicRootId);
|
||||
_occupiedHistory->clearCloudDraft(kTopicRootId, kMonoforumPeerId);
|
||||
_session->api().saveDraftToCloudDelayed(_occupiedHistory);
|
||||
}
|
||||
_occupiedHistory = history;
|
||||
|
@ -377,7 +378,10 @@ void Helper::occupyInDraft() {
|
|||
&& !isOccupiedBySomeone(_occupiedHistory)
|
||||
&& !_supportName.isEmpty()) {
|
||||
const auto draft = OccupiedDraft(_supportNameNormalized);
|
||||
_occupiedHistory->createCloudDraft(kTopicRootId, &draft);
|
||||
_occupiedHistory->createCloudDraft(
|
||||
kTopicRootId,
|
||||
kMonoforumPeerId,
|
||||
&draft);
|
||||
_session->api().saveDraftToCloudDelayed(_occupiedHistory);
|
||||
_reoccupyTimer.callEach(kReoccupyEach);
|
||||
}
|
||||
|
@ -386,7 +390,10 @@ void Helper::occupyInDraft() {
|
|||
void Helper::reoccupy() {
|
||||
if (isOccupiedByMe(_occupiedHistory)) {
|
||||
const auto draft = OccupiedDraft(_supportNameNormalized);
|
||||
_occupiedHistory->createCloudDraft(kTopicRootId, &draft);
|
||||
_occupiedHistory->createCloudDraft(
|
||||
kTopicRootId,
|
||||
kMonoforumPeerId,
|
||||
&draft);
|
||||
_session->api().saveDraftToCloudDelayed(_occupiedHistory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1802,8 +1802,10 @@ void PeerMenuCreatePoll(
|
|||
peer->owner().history(peer),
|
||||
result.options);
|
||||
action.replyTo = replyTo;
|
||||
const auto topicRootId = replyTo.topicRootId;
|
||||
if (const auto local = action.history->localDraft(topicRootId)) {
|
||||
const auto local = action.history->localDraft(
|
||||
replyTo.topicRootId,
|
||||
replyTo.monoforumPeerId);
|
||||
if (local) {
|
||||
action.clearDraft = local->textWithTags.text.isEmpty();
|
||||
} else {
|
||||
action.clearDraft = false;
|
||||
|
|
|
@ -2150,8 +2150,9 @@ bool SessionController::switchInlineQuery(
|
|||
params);
|
||||
} else {
|
||||
const auto topicRootId = to.currentReplyTo.topicRootId;
|
||||
const auto monoforumPeerId = to.currentReplyTo.monoforumPeerId;
|
||||
history->setLocalDraft(std::move(draft));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->clearLocalEditDraft(topicRootId, monoforumPeerId);
|
||||
if (to.section == Section::Replies) {
|
||||
const auto commentId = MsgId();
|
||||
showRepliesForMessage(history, topicRootId, commentId, params);
|
||||
|
|
Loading…
Add table
Reference in a new issue