mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Always write local drafts the same way.
This commit is contained in:
parent
f2da34c9f5
commit
85e4c8527b
6 changed files with 210 additions and 80 deletions
|
@ -1440,14 +1440,7 @@ void HistoryWidget::saveCloudDraft() {
|
||||||
void HistoryWidget::writeDraftTexts() {
|
void HistoryWidget::writeDraftTexts() {
|
||||||
Expects(_history != nullptr);
|
Expects(_history != nullptr);
|
||||||
|
|
||||||
session().local().writeDrafts(
|
session().local().writeDrafts(_history);
|
||||||
_history,
|
|
||||||
_editMsgId ? Data::DraftKey::LocalEdit() : Data::DraftKey::Local(),
|
|
||||||
Storage::MessageDraft{
|
|
||||||
_editMsgId ? _editMsgId : _replyToId,
|
|
||||||
_field->getTextWithTags(),
|
|
||||||
_previewState,
|
|
||||||
});
|
|
||||||
if (_migrated) {
|
if (_migrated) {
|
||||||
_migrated->clearDrafts();
|
_migrated->clearDrafts();
|
||||||
session().local().writeDrafts(_migrated);
|
session().local().writeDrafts(_migrated);
|
||||||
|
@ -1457,10 +1450,7 @@ void HistoryWidget::writeDraftTexts() {
|
||||||
void HistoryWidget::writeDraftCursors() {
|
void HistoryWidget::writeDraftCursors() {
|
||||||
Expects(_history != nullptr);
|
Expects(_history != nullptr);
|
||||||
|
|
||||||
session().local().writeDraftCursors(
|
session().local().writeDraftCursors(_history);
|
||||||
_history,
|
|
||||||
_editMsgId ? Data::DraftKey::LocalEdit() : Data::DraftKey::Local(),
|
|
||||||
MessageCursor(_field));
|
|
||||||
if (_migrated) {
|
if (_migrated) {
|
||||||
_migrated->clearDrafts();
|
_migrated->clearDrafts();
|
||||||
session().local().writeDraftCursors(_migrated);
|
session().local().writeDraftCursors(_migrated);
|
||||||
|
@ -1691,7 +1681,8 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
clearFieldText(0, fieldHistoryAction);
|
clearFieldText(0, fieldHistoryAction);
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
_replyEditMsg = nullptr;
|
_replyEditMsg = nullptr;
|
||||||
_editMsgId = _replyToId = 0;
|
_replyToId = 0;
|
||||||
|
setEditMsgId(0);
|
||||||
if (fieldWillBeHiddenAfterEdit) {
|
if (fieldWillBeHiddenAfterEdit) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
@ -1715,11 +1706,11 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
|
|
||||||
_replyEditMsg = nullptr;
|
_replyEditMsg = nullptr;
|
||||||
if (const auto editDraft = _history->localEditDraft()) {
|
if (const auto editDraft = _history->localEditDraft()) {
|
||||||
_editMsgId = editDraft->msgId;
|
setEditMsgId(editDraft->msgId);
|
||||||
_replyToId = 0;
|
_replyToId = 0;
|
||||||
} else {
|
} else {
|
||||||
_editMsgId = 0;
|
|
||||||
_replyToId = readyToForward() ? 0 : _history->localDraft()->msgId;
|
_replyToId = readyToForward() ? 0 : _history->localDraft()->msgId;
|
||||||
|
setEditMsgId(0);
|
||||||
}
|
}
|
||||||
updateCmdStartShown();
|
updateCmdStartShown();
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -1875,7 +1866,7 @@ void HistoryWidget::showHistory(
|
||||||
_scrollToAnimation.stop();
|
_scrollToAnimation.stop();
|
||||||
|
|
||||||
clearAllLoadRequests();
|
clearAllLoadRequests();
|
||||||
_history = _migrated = nullptr;
|
setHistory(nullptr);
|
||||||
_list = nullptr;
|
_list = nullptr;
|
||||||
_peer = nullptr;
|
_peer = nullptr;
|
||||||
_channel = NoChannel;
|
_channel = NoChannel;
|
||||||
|
@ -1944,8 +1935,7 @@ void HistoryWidget::showHistory(
|
||||||
_itemsRevealHeight = 0;
|
_itemsRevealHeight = 0;
|
||||||
|
|
||||||
if (_peer) {
|
if (_peer) {
|
||||||
_history = _peer->owner().history(_peer);
|
setHistory(_peer->owner().history(_peer));
|
||||||
_migrated = _history->migrateFrom();
|
|
||||||
if (_migrated
|
if (_migrated
|
||||||
&& !_migrated->isEmpty()
|
&& !_migrated->isEmpty()
|
||||||
&& (!_history->loadedAtTop() || !_migrated->loadedAtBottom())) {
|
&& (!_history->loadedAtTop() || !_migrated->loadedAtBottom())) {
|
||||||
|
@ -2072,6 +2062,56 @@ void HistoryWidget::showHistory(
|
||||||
crl::on_main(this, [=] { controller()->widget()->setInnerFocus(); });
|
crl::on_main(this, [=] { controller()->widget()->setInnerFocus(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::setHistory(History *history) {
|
||||||
|
if (_history == history) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unregisterDraftSources();
|
||||||
|
_history = history;
|
||||||
|
_migrated = _history ? _history->migrateFrom() : nullptr;
|
||||||
|
registerDraftSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::unregisterDraftSources() {
|
||||||
|
if (!_history) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
session().local().unregisterDraftSource(
|
||||||
|
_history,
|
||||||
|
Data::DraftKey::Local());
|
||||||
|
session().local().unregisterDraftSource(
|
||||||
|
_history,
|
||||||
|
Data::DraftKey::LocalEdit());
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::registerDraftSource() {
|
||||||
|
if (!_history) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto editMsgId = _editMsgId;
|
||||||
|
const auto draft = [=] {
|
||||||
|
return Storage::MessageDraft{
|
||||||
|
editMsgId ? editMsgId : _replyToId,
|
||||||
|
_field->getTextWithTags(),
|
||||||
|
_previewState,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
auto draftSource = Storage::MessageDraftSource{
|
||||||
|
.draft = draft,
|
||||||
|
.cursor = [=] { return MessageCursor(_field); },
|
||||||
|
};
|
||||||
|
session().local().registerDraftSource(
|
||||||
|
_history,
|
||||||
|
editMsgId ? Data::DraftKey::LocalEdit() : Data::DraftKey::Local(),
|
||||||
|
std::move(draftSource));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::setEditMsgId(MsgId msgId) {
|
||||||
|
unregisterDraftSources();
|
||||||
|
_editMsgId = msgId;
|
||||||
|
registerDraftSource();
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::clearDelayedShowAt() {
|
void HistoryWidget::clearDelayedShowAt() {
|
||||||
_delayedShowAtMsgId = -1;
|
_delayedShowAtMsgId = -1;
|
||||||
clearDelayedShowAtRequest();
|
clearDelayedShowAtRequest();
|
||||||
|
@ -6122,7 +6162,7 @@ void HistoryWidget::cancelEdit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_replyEditMsg = nullptr;
|
_replyEditMsg = nullptr;
|
||||||
_editMsgId = 0;
|
setEditMsgId(0);
|
||||||
_history->clearLocalEditDraft();
|
_history->clearLocalEditDraft();
|
||||||
applyDraft();
|
applyDraft();
|
||||||
|
|
||||||
|
@ -6998,6 +7038,7 @@ HistoryWidget::~HistoryWidget() {
|
||||||
session().api().saveDraftToCloudDelayed(_history);
|
session().api().saveDraftToCloudDelayed(_history);
|
||||||
|
|
||||||
clearAllLoadRequests();
|
clearAllLoadRequests();
|
||||||
|
unregisterDraftSources();
|
||||||
}
|
}
|
||||||
setTabbedPanel(nullptr);
|
setTabbedPanel(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,6 +558,11 @@ private:
|
||||||
TextUpdateEvents events = 0,
|
TextUpdateEvents events = 0,
|
||||||
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
||||||
|
|
||||||
|
void unregisterDraftSources();
|
||||||
|
void registerDraftSource();
|
||||||
|
void setHistory(History *history);
|
||||||
|
void setEditMsgId(MsgId msgId);
|
||||||
|
|
||||||
HistoryItem *getItemFromHistoryOrMigrated(MsgId genericMsgId) const;
|
HistoryItem *getItemFromHistoryOrMigrated(MsgId genericMsgId) const;
|
||||||
void animatedScrollToItem(MsgId msgId);
|
void animatedScrollToItem(MsgId msgId);
|
||||||
void animatedScrollToY(int scrollTo, HistoryItem *attachTo = nullptr);
|
void animatedScrollToY(int scrollTo, HistoryItem *attachTo = nullptr);
|
||||||
|
|
|
@ -626,6 +626,7 @@ ComposeControls::ComposeControls(
|
||||||
|
|
||||||
ComposeControls::~ComposeControls() {
|
ComposeControls::~ComposeControls() {
|
||||||
saveFieldToHistoryLocalDraft();
|
saveFieldToHistoryLocalDraft();
|
||||||
|
unregisterDraftSources();
|
||||||
setTabbedPanel(nullptr);
|
setTabbedPanel(nullptr);
|
||||||
session().api().request(_inlineBotResolveRequestId).cancel();
|
session().api().request(_inlineBotResolveRequestId).cancel();
|
||||||
}
|
}
|
||||||
|
@ -650,7 +651,9 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
|
||||||
//if (_history == history) {
|
//if (_history == history) {
|
||||||
// return;
|
// return;
|
||||||
//}
|
//}
|
||||||
|
unregisterDraftSources();
|
||||||
_history = history;
|
_history = history;
|
||||||
|
registerDraftSource();
|
||||||
_window->tabbedSelector()->setCurrentPeer(
|
_window->tabbedSelector()->setCurrentPeer(
|
||||||
history ? history->peer.get() : nullptr);
|
history ? history->peer.get() : nullptr);
|
||||||
initWebpageProcess();
|
initWebpageProcess();
|
||||||
|
@ -877,7 +880,11 @@ TextWithTags ComposeControls::getTextWithAppliedMarkdown() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::clear() {
|
void ComposeControls::clear() {
|
||||||
setText({});
|
// Otherwise cancelReplyMessage() will save the draft.
|
||||||
|
const auto saveTextDraft = !replyingToMessage();
|
||||||
|
setFieldText(
|
||||||
|
{},
|
||||||
|
saveTextDraft ? TextUpdateEvent::SaveDraft : TextUpdateEvent());
|
||||||
cancelReplyMessage();
|
cancelReplyMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +1000,9 @@ void ComposeControls::init() {
|
||||||
|
|
||||||
_header->editMsgId(
|
_header->editMsgId(
|
||||||
) | rpl::start_with_next([=](const auto &id) {
|
) | rpl::start_with_next([=](const auto &id) {
|
||||||
|
unregisterDraftSources();
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
|
registerDraftSource();
|
||||||
}, _wrap->lifetime());
|
}, _wrap->lifetime());
|
||||||
|
|
||||||
_header->previewCancelled(
|
_header->previewCancelled(
|
||||||
|
@ -1396,23 +1405,51 @@ void ComposeControls::saveDraft(bool delayed) {
|
||||||
void ComposeControls::writeDraftTexts() {
|
void ComposeControls::writeDraftTexts() {
|
||||||
Expects(_history != nullptr);
|
Expects(_history != nullptr);
|
||||||
|
|
||||||
session().local().writeDrafts(
|
session().local().writeDrafts(_history);
|
||||||
_history,
|
|
||||||
draftKeyCurrent(),
|
|
||||||
Storage::MessageDraft{
|
|
||||||
_header->getDraftMessageId(),
|
|
||||||
_field->getTextWithTags(),
|
|
||||||
_previewState,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::writeDraftCursors() {
|
void ComposeControls::writeDraftCursors() {
|
||||||
Expects(_history != nullptr);
|
Expects(_history != nullptr);
|
||||||
|
|
||||||
session().local().writeDraftCursors(
|
session().local().writeDraftCursors(_history);
|
||||||
_history,
|
}
|
||||||
draftKeyCurrent(),
|
|
||||||
MessageCursor(_field));
|
void ComposeControls::unregisterDraftSources() {
|
||||||
|
if (!_history) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto normal = draftKey(DraftType::Normal);
|
||||||
|
const auto edit = draftKey(DraftType::Edit);
|
||||||
|
if (normal != Data::DraftKey::None()) {
|
||||||
|
session().local().unregisterDraftSource(_history, normal);
|
||||||
|
}
|
||||||
|
if (edit != Data::DraftKey::None()) {
|
||||||
|
session().local().unregisterDraftSource(_history, edit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComposeControls::registerDraftSource() {
|
||||||
|
if (!_history) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto key = draftKeyCurrent();
|
||||||
|
if (key != Data::DraftKey::None()) {
|
||||||
|
const auto draft = [=] {
|
||||||
|
return Storage::MessageDraft{
|
||||||
|
_header->getDraftMessageId(),
|
||||||
|
_field->getTextWithTags(),
|
||||||
|
_previewState,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
auto draftSource = Storage::MessageDraftSource{
|
||||||
|
.draft = draft,
|
||||||
|
.cursor = [=] { return MessageCursor(_field); },
|
||||||
|
};
|
||||||
|
session().local().registerDraftSource(
|
||||||
|
_history,
|
||||||
|
key,
|
||||||
|
std::move(draftSource));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::writeDrafts() {
|
void ComposeControls::writeDrafts() {
|
||||||
|
|
|
@ -270,6 +270,9 @@ private:
|
||||||
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
|
||||||
void saveFieldToHistoryLocalDraft();
|
void saveFieldToHistoryLocalDraft();
|
||||||
|
|
||||||
|
void unregisterDraftSources();
|
||||||
|
void registerDraftSource();
|
||||||
|
|
||||||
const not_null<QWidget*> _parent;
|
const not_null<QWidget*> _parent;
|
||||||
const not_null<Window::SessionController*> _window;
|
const not_null<Window::SessionController*> _window;
|
||||||
History *_history = nullptr;
|
History *_history = nullptr;
|
||||||
|
|
|
@ -52,6 +52,7 @@ constexpr auto kSinglePeerTypeChannel = qint32(3);
|
||||||
constexpr auto kSinglePeerTypeSelf = qint32(4);
|
constexpr auto kSinglePeerTypeSelf = qint32(4);
|
||||||
constexpr auto kSinglePeerTypeEmpty = qint32(0);
|
constexpr auto kSinglePeerTypeEmpty = qint32(0);
|
||||||
constexpr auto kMultiDraftTag = quint64(0xFFFFFFFFFFFFFF01ULL);
|
constexpr auto kMultiDraftTag = quint64(0xFFFFFFFFFFFFFF01ULL);
|
||||||
|
constexpr auto kMultiDraftCursorsTag = quint64(0xFFFFFFFFFFFFFF02ULL);
|
||||||
|
|
||||||
enum { // Local Storage Keys
|
enum { // Local Storage Keys
|
||||||
lskUserMap = 0x00,
|
lskUserMap = 0x00,
|
||||||
|
@ -79,6 +80,14 @@ enum { // Local Storage Keys
|
||||||
lskMasksKeys = 0x16, // no data
|
lskMasksKeys = 0x16, // no data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto EmptyMessageDraftSources()
|
||||||
|
-> const base::flat_map<Data::DraftKey, MessageDraftSource> & {
|
||||||
|
static const auto result = base::flat_map<
|
||||||
|
Data::DraftKey,
|
||||||
|
MessageDraftSource>();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] FileKey ComputeDataNameKey(const QString &dataName) {
|
[[nodiscard]] FileKey ComputeDataNameKey(const QString &dataName) {
|
||||||
// We dropped old test authorizations when migrated to multi auth.
|
// We dropped old test authorizations when migrated to multi auth.
|
||||||
//const auto testAddition = (cTestMode() ? qsl(":/test/") : QString());
|
//const auto testAddition = (cTestMode() ? qsl(":/test/") : QString());
|
||||||
|
@ -957,12 +966,10 @@ void EnumerateDrafts(
|
||||||
const Data::HistoryDrafts &map,
|
const Data::HistoryDrafts &map,
|
||||||
Data::Draft *cloudDraft,
|
Data::Draft *cloudDraft,
|
||||||
bool supportMode,
|
bool supportMode,
|
||||||
Data::DraftKey replaceKey,
|
const base::flat_map<Data::DraftKey, MessageDraftSource> &sources,
|
||||||
const MessageDraft &replaceDraft,
|
|
||||||
const MessageCursor &replaceCursor,
|
|
||||||
Callback &&callback) {
|
Callback &&callback) {
|
||||||
for (const auto &[key, draft] : map) {
|
for (const auto &[key, draft] : map) {
|
||||||
if (key == Data::DraftKey::Cloud() || key == replaceKey) {
|
if (key == Data::DraftKey::Cloud() || sources.contains(key)) {
|
||||||
continue;
|
continue;
|
||||||
} else if (key == Data::DraftKey::Local()
|
} else if (key == Data::DraftKey::Local()
|
||||||
&& !supportMode
|
&& !supportMode
|
||||||
|
@ -976,23 +983,45 @@ void EnumerateDrafts(
|
||||||
draft->previewState,
|
draft->previewState,
|
||||||
draft->cursor);
|
draft->cursor);
|
||||||
}
|
}
|
||||||
if (replaceKey
|
for (const auto &[key, source] : sources) {
|
||||||
&& (replaceDraft.msgId
|
const auto draft = source.draft();
|
||||||
|| !replaceDraft.textWithTags.text.isEmpty()
|
const auto cursor = source.cursor();
|
||||||
|| replaceCursor != MessageCursor())) {
|
if (draft.msgId
|
||||||
callback(
|
|| !draft.textWithTags.text.isEmpty()
|
||||||
replaceKey,
|
|| cursor != MessageCursor()) {
|
||||||
replaceDraft.msgId,
|
callback(
|
||||||
replaceDraft.textWithTags,
|
key,
|
||||||
replaceDraft.previewState,
|
draft.msgId,
|
||||||
replaceCursor);
|
draft.textWithTags,
|
||||||
|
draft.previewState,
|
||||||
|
cursor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::writeDrafts(
|
void Account::registerDraftSource(
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
Data::DraftKey replaceKey,
|
Data::DraftKey key,
|
||||||
MessageDraft replaceDraft) {
|
MessageDraftSource source) {
|
||||||
|
Expects(source.draft != nullptr);
|
||||||
|
Expects(source.cursor != nullptr);
|
||||||
|
|
||||||
|
_draftSources[history][key] = std::move(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Account::unregisterDraftSource(
|
||||||
|
not_null<History*> history,
|
||||||
|
Data::DraftKey key) {
|
||||||
|
const auto i = _draftSources.find(history);
|
||||||
|
if (i != _draftSources.end()) {
|
||||||
|
i->second.remove(key);
|
||||||
|
if (i->second.empty()) {
|
||||||
|
_draftSources.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Account::writeDrafts(not_null<History*> history) {
|
||||||
const auto peerId = history->peer->id;
|
const auto peerId = history->peer->id;
|
||||||
const auto &map = history->draftsMap();
|
const auto &map = history->draftsMap();
|
||||||
const auto cloudIt = map.find(Data::DraftKey::Cloud());
|
const auto cloudIt = map.find(Data::DraftKey::Cloud());
|
||||||
|
@ -1000,14 +1029,16 @@ void Account::writeDrafts(
|
||||||
? cloudIt->second.get()
|
? cloudIt->second.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto supportMode = _owner->session().supportMode();
|
const auto supportMode = _owner->session().supportMode();
|
||||||
|
const auto sourcesIt = _draftSources.find(history);
|
||||||
|
const auto &sources = (sourcesIt != _draftSources.end())
|
||||||
|
? sourcesIt->second
|
||||||
|
: EmptyMessageDraftSources();
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
EnumerateDrafts(
|
EnumerateDrafts(
|
||||||
map,
|
map,
|
||||||
cloudDraft,
|
cloudDraft,
|
||||||
supportMode,
|
supportMode,
|
||||||
replaceKey,
|
sources,
|
||||||
replaceDraft,
|
|
||||||
MessageCursor(),
|
|
||||||
[&](auto&&...) { ++count; });
|
[&](auto&&...) { ++count; });
|
||||||
if (!count) {
|
if (!count) {
|
||||||
auto i = _draftsMap.find(peerId);
|
auto i = _draftsMap.find(peerId);
|
||||||
|
@ -1043,9 +1074,7 @@ void Account::writeDrafts(
|
||||||
map,
|
map,
|
||||||
cloudDraft,
|
cloudDraft,
|
||||||
supportMode,
|
supportMode,
|
||||||
replaceKey,
|
sources,
|
||||||
replaceDraft,
|
|
||||||
MessageCursor(),
|
|
||||||
sizeCallback);
|
sizeCallback);
|
||||||
|
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
|
@ -1071,9 +1100,7 @@ void Account::writeDrafts(
|
||||||
map,
|
map,
|
||||||
cloudDraft,
|
cloudDraft,
|
||||||
supportMode,
|
supportMode,
|
||||||
replaceKey,
|
sources,
|
||||||
replaceDraft,
|
|
||||||
MessageCursor(),
|
|
||||||
writeCallback);
|
writeCallback);
|
||||||
|
|
||||||
FileWriteDescriptor file(i->second, _basePath);
|
FileWriteDescriptor file(i->second, _basePath);
|
||||||
|
@ -1082,10 +1109,7 @@ void Account::writeDrafts(
|
||||||
_draftsNotReadMap.remove(peerId);
|
_draftsNotReadMap.remove(peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::writeDraftCursors(
|
void Account::writeDraftCursors(not_null<History*> history) {
|
||||||
not_null<History*> history,
|
|
||||||
Data::DraftKey replaceKey,
|
|
||||||
MessageCursor replaceCursor) {
|
|
||||||
const auto peerId = history->peer->id;
|
const auto peerId = history->peer->id;
|
||||||
const auto &map = history->draftsMap();
|
const auto &map = history->draftsMap();
|
||||||
const auto cloudIt = map.find(Data::DraftKey::Cloud());
|
const auto cloudIt = map.find(Data::DraftKey::Cloud());
|
||||||
|
@ -1093,14 +1117,16 @@ void Account::writeDraftCursors(
|
||||||
? cloudIt->second.get()
|
? cloudIt->second.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto supportMode = _owner->session().supportMode();
|
const auto supportMode = _owner->session().supportMode();
|
||||||
|
const auto sourcesIt = _draftSources.find(history);
|
||||||
|
const auto &sources = (sourcesIt != _draftSources.end())
|
||||||
|
? sourcesIt->second
|
||||||
|
: EmptyMessageDraftSources();
|
||||||
auto count = 0;
|
auto count = 0;
|
||||||
EnumerateDrafts(
|
EnumerateDrafts(
|
||||||
map,
|
map,
|
||||||
cloudDraft,
|
cloudDraft,
|
||||||
supportMode,
|
supportMode,
|
||||||
replaceKey,
|
sources,
|
||||||
MessageDraft(),
|
|
||||||
replaceCursor,
|
|
||||||
[&](auto&&...) { ++count; });
|
[&](auto&&...) { ++count; });
|
||||||
if (!count) {
|
if (!count) {
|
||||||
clearDraftCursors(peerId);
|
clearDraftCursors(peerId);
|
||||||
|
@ -1112,21 +1138,24 @@ void Account::writeDraftCursors(
|
||||||
writeMapQueued();
|
writeMapQueued();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = int(sizeof(quint64) * 2 + sizeof(quint32) * 4);
|
auto size = int(sizeof(quint64) * 2
|
||||||
|
+ sizeof(quint32)
|
||||||
|
+ sizeof(qint32) * 4 * count);
|
||||||
|
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
data.stream
|
data.stream
|
||||||
<< quint64(kMultiDraftTag)
|
<< quint64(kMultiDraftCursorsTag)
|
||||||
<< SerializePeerId(peerId)
|
<< SerializePeerId(peerId)
|
||||||
<< quint32(count);
|
<< quint32(count);
|
||||||
|
|
||||||
const auto writeCallback = [&](
|
const auto writeCallback = [&](
|
||||||
auto&&, // key
|
const Data::DraftKey &key,
|
||||||
MsgId, // msgId
|
MsgId, // msgId
|
||||||
auto&&, // text
|
auto&&, // text
|
||||||
Data::PreviewState,
|
Data::PreviewState,
|
||||||
const MessageCursor &cursor) { // cursor
|
const MessageCursor &cursor) { // cursor
|
||||||
data.stream
|
data.stream
|
||||||
|
<< key.serialize()
|
||||||
<< qint32(cursor.position)
|
<< qint32(cursor.position)
|
||||||
<< qint32(cursor.anchor)
|
<< qint32(cursor.anchor)
|
||||||
<< qint32(cursor.scroll);
|
<< qint32(cursor.scroll);
|
||||||
|
@ -1135,9 +1164,7 @@ void Account::writeDraftCursors(
|
||||||
map,
|
map,
|
||||||
cloudDraft,
|
cloudDraft,
|
||||||
supportMode,
|
supportMode,
|
||||||
replaceKey,
|
sources,
|
||||||
MessageDraft(),
|
|
||||||
replaceCursor,
|
|
||||||
writeCallback);
|
writeCallback);
|
||||||
|
|
||||||
FileWriteDescriptor file(i->second, _basePath);
|
FileWriteDescriptor file(i->second, _basePath);
|
||||||
|
@ -1166,7 +1193,7 @@ void Account::readDraftCursors(PeerId peerId, Data::HistoryDrafts &map) {
|
||||||
}
|
}
|
||||||
quint64 tag = 0;
|
quint64 tag = 0;
|
||||||
draft.stream >> tag;
|
draft.stream >> tag;
|
||||||
if (tag != kMultiDraftTag) {
|
if (tag != kMultiDraftTag && tag != kMultiDraftCursorsTag) {
|
||||||
readDraftCursorsLegacy(peerId, draft, tag, map);
|
readDraftCursorsLegacy(peerId, draft, tag, map);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1178,10 +1205,18 @@ void Account::readDraftCursors(PeerId peerId, Data::HistoryDrafts &map) {
|
||||||
clearDraftCursors(peerId);
|
clearDraftCursors(peerId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto keysWritten = (tag == kMultiDraftCursorsTag);
|
||||||
for (auto i = 0; i != count; ++i) {
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
qint32 keyValue = 0;
|
||||||
|
if (keysWritten) {
|
||||||
|
draft.stream >> keyValue;
|
||||||
|
}
|
||||||
|
const auto key = keysWritten
|
||||||
|
? Data::DraftKey::FromSerialized(keyValue)
|
||||||
|
: Data::DraftKey::Local();
|
||||||
qint32 position = 0, anchor = 0, scroll = QFIXED_MAX;
|
qint32 position = 0, anchor = 0, scroll = QFIXED_MAX;
|
||||||
draft.stream >> position >> anchor >> scroll;
|
draft.stream >> position >> anchor >> scroll;
|
||||||
if (const auto i = map.find(Data::DraftKey::Local()); i != end(map)) {
|
if (const auto i = map.find(key); i != end(map)) {
|
||||||
i->second->cursor = MessageCursor(position, anchor, scroll);
|
i->second->cursor = MessageCursor(position, anchor, scroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,11 @@ struct MessageDraft {
|
||||||
Data::PreviewState previewState = Data::PreviewState::Allowed;
|
Data::PreviewState previewState = Data::PreviewState::Allowed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MessageDraftSource {
|
||||||
|
Fn<MessageDraft()> draft;
|
||||||
|
Fn<MessageCursor()> cursor;
|
||||||
|
};
|
||||||
|
|
||||||
class Account final {
|
class Account final {
|
||||||
public:
|
public:
|
||||||
Account(not_null<Main::Account*> owner, const QString &dataName);
|
Account(not_null<Main::Account*> owner, const QString &dataName);
|
||||||
|
@ -79,15 +84,16 @@ public:
|
||||||
void writeMtpData();
|
void writeMtpData();
|
||||||
void writeMtpConfig();
|
void writeMtpConfig();
|
||||||
|
|
||||||
void writeDrafts(
|
void registerDraftSource(
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
Data::DraftKey replaceKey = Data::DraftKey::None(),
|
Data::DraftKey key,
|
||||||
MessageDraft replaceDraft = MessageDraft());
|
MessageDraftSource source);
|
||||||
|
void unregisterDraftSource(
|
||||||
|
not_null<History*> history,
|
||||||
|
Data::DraftKey key);
|
||||||
|
void writeDrafts(not_null<History*> history);
|
||||||
void readDraftsWithCursors(not_null<History*> history);
|
void readDraftsWithCursors(not_null<History*> history);
|
||||||
void writeDraftCursors(
|
void writeDraftCursors(not_null<History*> history);
|
||||||
not_null<History*> history,
|
|
||||||
Data::DraftKey replaceKey = Data::DraftKey::None(),
|
|
||||||
MessageCursor replaceCursor = MessageCursor());
|
|
||||||
[[nodiscard]] bool hasDraftCursors(PeerId peerId);
|
[[nodiscard]] bool hasDraftCursors(PeerId peerId);
|
||||||
[[nodiscard]] bool hasDraft(PeerId peerId);
|
[[nodiscard]] bool hasDraft(PeerId peerId);
|
||||||
|
|
||||||
|
@ -242,6 +248,9 @@ private:
|
||||||
base::flat_map<PeerId, FileKey> _draftsMap;
|
base::flat_map<PeerId, FileKey> _draftsMap;
|
||||||
base::flat_map<PeerId, FileKey> _draftCursorsMap;
|
base::flat_map<PeerId, FileKey> _draftCursorsMap;
|
||||||
base::flat_map<PeerId, bool> _draftsNotReadMap;
|
base::flat_map<PeerId, bool> _draftsNotReadMap;
|
||||||
|
base::flat_map<
|
||||||
|
not_null<History*>,
|
||||||
|
base::flat_map<Data::DraftKey, MessageDraftSource>> _draftSources;
|
||||||
|
|
||||||
QMultiMap<MediaKey, Core::FileLocation> _fileLocations;
|
QMultiMap<MediaKey, Core::FileLocation> _fileLocations;
|
||||||
QMap<QString, QPair<MediaKey, Core::FileLocation>> _fileLocationPairs;
|
QMap<QString, QPair<MediaKey, Core::FileLocation>> _fileLocationPairs;
|
||||||
|
|
Loading…
Add table
Reference in a new issue