From a4285343458a2a98c0cce3a15fdd2fd3bb99556f Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 9 Jun 2016 17:31:10 +0300 Subject: [PATCH] Cloud draft handling improved. Fixed Edit while already editing a msg. --- Telegram/SourceFiles/apiwrap.cpp | 3 +- Telegram/SourceFiles/app.cpp | 4 +- Telegram/SourceFiles/data/data_drafts.cpp | 17 +++- Telegram/SourceFiles/data/data_drafts.h | 50 +++++++++++ .../SourceFiles/dialogs/dialogs_layout.cpp | 3 +- Telegram/SourceFiles/history.cpp | 54 +++++++++-- Telegram/SourceFiles/history.h | 90 ++++--------------- Telegram/SourceFiles/historywidget.cpp | 82 +++++++---------- Telegram/SourceFiles/historywidget.h | 2 +- Telegram/SourceFiles/localstorage.cpp | 5 +- Telegram/SourceFiles/mainwidget.cpp | 27 +++++- Telegram/SourceFiles/mainwidget.h | 1 + Telegram/Telegram.vcxproj | 1 - Telegram/Telegram.vcxproj.filters | 3 - 14 files changed, 197 insertions(+), 145 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 661004e48..0a13d6be2 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "apiwrap.h" +#include "data/data_drafts.h" #include "observer_peer.h" #include "lang.h" #include "application.h" @@ -851,7 +852,7 @@ void ApiWrap::saveCloudDraftDone(History *history, const MTPBool &result, mtpReq if (auto cloudDraft = history->cloudDraft()) { if (cloudDraft->saveRequestId == requestId) { cloudDraft->saveRequestId = 0; - history->updateChatListEntry(); + history->draftSavedToCloud(); } } auto i = _draftsSaveRequestIds.find(history); diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 532b64e86..c05e0624e 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -286,10 +286,10 @@ namespace { QString onlineText(UserData *user, TimeId now, bool precise) { if (isNotificationsUser(user->id)) { return lang(lng_status_service_notifications); - } else if (isServiceUser(user->id)) { - return lang(lng_status_support); } else if (user->botInfo) { return lang(lng_status_bot); + } else if (isServiceUser(user->id)) { + return lang(lng_status_support); } return onlineText(user->onlineTill, now, precise); } diff --git a/Telegram/SourceFiles/data/data_drafts.cpp b/Telegram/SourceFiles/data/data_drafts.cpp index 9f6ba0691..8d33956b9 100644 --- a/Telegram/SourceFiles/data/data_drafts.cpp +++ b/Telegram/SourceFiles/data/data_drafts.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "historywidget.h" #include "mainwidget.h" +#include "localstorage.h" namespace Data { namespace { @@ -35,7 +36,7 @@ void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) { auto entities = draft.has_entities() ? entitiesFromMTP(draft.ventities.c_vector().v) : EntitiesInText(); TextWithTags textWithTags = { textApplyEntities(text, entities), textTagsFromEntities(entities) }; MsgId replyTo = draft.has_reply_to_msg_id() ? draft.vreply_to_msg_id.v : 0; - auto cloudDraft = std_::make_unique(textWithTags, replyTo, MessageCursor(QFIXED_MAX, QFIXED_MAX, QFIXED_MAX), draft.is_no_webpage()); + auto cloudDraft = std_::make_unique(textWithTags, replyTo, MessageCursor(QFIXED_MAX, QFIXED_MAX, QFIXED_MAX), draft.is_no_webpage()); cloudDraft->date = ::date(draft.vdate); history->setCloudDraft(std_::move(cloudDraft)); @@ -48,4 +49,18 @@ void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) { } } +void clearPeerCloudDraft(PeerId peerId) { + auto history = App::history(peerId); + + history->clearCloudDraft(); + history->clearLocalDraft(); + + history->updateChatListSortPosition(); + history->updateChatListEntry(); + + if (auto main = App::main()) { + main->applyCloudDraft(history); + } +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_drafts.h b/Telegram/SourceFiles/data/data_drafts.h index 3a3b948f7..bf8ad6064 100644 --- a/Telegram/SourceFiles/data/data_drafts.h +++ b/Telegram/SourceFiles/data/data_drafts.h @@ -23,5 +23,55 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Data { void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft); +void clearPeerCloudDraft(PeerId peerId); + +struct Draft { + Draft() { + } + Draft(const TextWithTags &textWithTags, MsgId msgId, const MessageCursor &cursor, bool previewCancelled, mtpRequestId saveRequestId = 0) + : textWithTags(textWithTags) + , msgId(msgId) + , cursor(cursor) + , previewCancelled(previewCancelled) + , saveRequestId(saveRequestId) { + } + Draft(const FlatTextarea &field, MsgId msgId, bool previewCancelled, mtpRequestId saveRequestId = 0) + : textWithTags(field.getTextWithTags()) + , msgId(msgId) + , cursor(field) + , previewCancelled(previewCancelled) { + } + QDateTime date; + TextWithTags textWithTags; + MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft + MessageCursor cursor; + bool previewCancelled = false; + mtpRequestId saveRequestId = 0; +}; + +inline bool draftStringIsEmpty(const QString &text) { + for_const (auto ch, text) { + if (!ch.isSpace()) { + return false; + } + } + return true; +} + +inline bool draftIsNull(Draft *draft) { + return !draft || draftStringIsEmpty(draft->textWithTags.text); +} + +inline bool draftsAreEqual(Draft *a, Draft *b) { + bool aIsNull = draftIsNull(a); + bool bIsNull = draftIsNull(b); + if (aIsNull) { + return bIsNull; + } else if (bIsNull) { + return false; + } + + return (a->textWithTags == b->textWithTags) && (a->msgId == b->msgId) && (a->previewCancelled == b->previewCancelled); +} } // namespace Data diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 06445fa1f..8cc4688f0 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dialogs/dialogs_layout.h" #include "data/data_abstract_structure.h" +#include "data/data_drafts.h" #include "dialogs/dialogs_list.h" #include "styles/style_dialogs.h" #include "localstorage.h" @@ -51,7 +52,7 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac } template -void paintRow(Painter &p, History *history, HistoryItem *item, HistoryDraft *draft, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) { +void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draft, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) { QRect fullRect(0, 0, w, st::dialogsRowHeight); p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg)); if (onlyBackground) return; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 8d50384d9..f7197c08e 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dialogs/dialogs_indexed_list.h" #include "styles/style_dialogs.h" #include "history/history_service_layout.h" +#include "data/data_drafts.h" #include "lang.h" #include "mainwidget.h" #include "application.h" @@ -168,14 +169,31 @@ void History::setHasPendingResizedItems() { Global::RefHandleHistoryUpdate().call(); } +void History::setLocalDraft(std_::unique_ptr &&draft) { + _localDraft = std_::move(draft); +} + +void History::takeLocalDraft(History *from) { + if (auto &draft = from->_localDraft) { + if (!draft->textWithTags.text.isEmpty() && !_localDraft) { + _localDraft = std_::move(draft); + + // Edit and reply to drafts can't migrate. + // Cloud drafts do not migrate automatically. + _localDraft->msgId = 0; + } + from->clearLocalDraft(); + } +} + void History::createLocalDraftFromCloud() { auto draft = cloudDraft(); - if (historyDraftIsNull(draft) || !draft->date.isValid()) return; + if (Data::draftIsNull(draft) || !draft->date.isValid()) return; auto existing = localDraft(); - if (historyDraftIsNull(existing) || !existing->date.isValid() || draft->date > existing->date) { + if (Data::draftIsNull(existing) || !existing->date.isValid() || draft->date >= existing->date) { if (!existing) { - setLocalDraft(std_::make_unique(draft->textWithTags, draft->msgId, draft->cursor, draft->previewCancelled)); + setLocalDraft(std_::make_unique(draft->textWithTags, draft->msgId, draft->cursor, draft->previewCancelled)); existing = localDraft(); } else if (existing != draft) { existing->textWithTags = draft->textWithTags; @@ -187,14 +205,19 @@ void History::createLocalDraftFromCloud() { } } -HistoryDraft *History::createCloudDraft(HistoryDraft *fromDraft) { - if (historyDraftIsNull(fromDraft)) { - setCloudDraft(std_::make_unique(TextWithTags(), 0, MessageCursor(), false)); +void History::setCloudDraft(std_::unique_ptr &&draft) { + _cloudDraft = std_::move(draft); + cloudDraftTextCache.clear(); +} + +Data::Draft *History::createCloudDraft(Data::Draft *fromDraft) { + if (Data::draftIsNull(fromDraft)) { + setCloudDraft(std_::make_unique(TextWithTags(), 0, MessageCursor(), false)); cloudDraft()->date = QDateTime(); } else { auto existing = cloudDraft(); if (!existing) { - setCloudDraft(std_::make_unique(fromDraft->textWithTags, fromDraft->msgId, fromDraft->cursor, fromDraft->previewCancelled)); + setCloudDraft(std_::make_unique(fromDraft->textWithTags, fromDraft->msgId, fromDraft->cursor, fromDraft->previewCancelled)); existing = cloudDraft(); } else if (existing != fromDraft) { existing->textWithTags = fromDraft->textWithTags; @@ -212,6 +235,14 @@ HistoryDraft *History::createCloudDraft(HistoryDraft *fromDraft) { return cloudDraft(); } +void History::setEditDraft(std_::unique_ptr &&draft) { + _editDraft = std_::move(draft); +} + +void History::clearLocalDraft() { + _localDraft = nullptr; +} + void History::clearCloudDraft() { if (_cloudDraft) { _cloudDraft = nullptr; @@ -221,6 +252,15 @@ void History::clearCloudDraft() { } } +void History::clearEditDraft() { + _editDraft = nullptr; +} + +void History::draftSavedToCloud() { + updateChatListEntry(); + if (App::main()) App::main()->writeDrafts(this); +} + bool History::updateTyping(uint64 ms, bool force) { bool changed = force; for (TypingUsers::iterator i = typing.begin(), e = typing.end(); i != e;) { diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 523859043..3c4782fdf 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -154,45 +154,10 @@ struct SendAction { }; using TextWithTags = FlatTextarea::TextWithTags; -struct HistoryDraft { - HistoryDraft() { - } - HistoryDraft(const TextWithTags &textWithTags, MsgId msgId, const MessageCursor &cursor, bool previewCancelled, mtpRequestId saveRequestId = 0) - : textWithTags(textWithTags) - , msgId(msgId) - , cursor(cursor) - , previewCancelled(previewCancelled) - , saveRequestId(saveRequestId) { - } - HistoryDraft(const FlatTextarea &field, MsgId msgId, bool previewCancelled, mtpRequestId saveRequestId = 0) - : textWithTags(field.getTextWithTags()) - , msgId(msgId) - , cursor(field) - , previewCancelled(previewCancelled) { - } - QDateTime date; - TextWithTags textWithTags; - MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft - MessageCursor cursor; - bool previewCancelled = false; - mtpRequestId saveRequestId = 0; -}; -inline bool historyDraftIsNull(HistoryDraft *draft) { - return (!draft || (!draft->msgId && draft->textWithTags.text.isEmpty())); -} - -inline bool historyDraftsAreEqual(HistoryDraft *a, HistoryDraft *b) { - bool aIsNull = historyDraftIsNull(a); - bool bIsNull = historyDraftIsNull(b); - if (aIsNull) { - return bIsNull; - } else if (bIsNull) { - return false; - } - - return (a->textWithTags == b->textWithTags) && (a->msgId == b->msgId) && (a->previewCancelled == b->previewCancelled); -} +namespace Data { +struct Draft; +} // namespace Data class HistoryMedia; class HistoryMessage; @@ -373,47 +338,26 @@ public: typedef QList NotifyQueue; NotifyQueue notifies; - HistoryDraft *localDraft() { + Data::Draft *localDraft() { return _localDraft.get(); } - HistoryDraft *cloudDraft() { + Data::Draft *cloudDraft() { return _cloudDraft.get(); } - HistoryDraft *editDraft() { + Data::Draft *editDraft() { return _editDraft.get(); } - void setLocalDraft(std_::unique_ptr &&draft) { - _localDraft = std_::move(draft); - } - void takeLocalDraft(History *from) { - if (auto &draft = from->_localDraft) { - if (!draft->textWithTags.text.isEmpty() && !_localDraft) { - _localDraft = std_::move(draft); - - // Edit and reply to drafts can't migrate. - // Cloud drafts do not migrate automatically. - _localDraft->msgId = 0; - } - from->clearLocalDraft(); - } - } + void setLocalDraft(std_::unique_ptr &&draft); + void takeLocalDraft(History *from); void createLocalDraftFromCloud(); - void setCloudDraft(std_::unique_ptr &&draft) { - _cloudDraft = std_::move(draft); - cloudDraftTextCache.clear(); - } - HistoryDraft *createCloudDraft(HistoryDraft *fromDraft); - void setEditDraft(std_::unique_ptr &&draft) { - _editDraft = std_::move(draft); - } - void clearLocalDraft() { - _localDraft = nullptr; - } + void setCloudDraft(std_::unique_ptr &&draft); + Data::Draft *createCloudDraft(Data::Draft *fromDraft); + void setEditDraft(std_::unique_ptr &&draft); + void clearLocalDraft(); void clearCloudDraft(); - void clearEditDraft() { - _editDraft = nullptr; - } - HistoryDraft *draft() { + void clearEditDraft(); + void draftSavedToCloud(); + Data::Draft *draft() { return _editDraft ? editDraft() : localDraft(); } @@ -599,8 +543,8 @@ private: // Depending on isBuildingFrontBlock() gets front or back block. HistoryBlock *prepareBlockForAddingItem(); - std_::unique_ptr _localDraft, _cloudDraft; - std_::unique_ptr _editDraft; + std_::unique_ptr _localDraft, _cloudDraft; + std_::unique_ptr _editDraft; }; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 282a5e7fe..55bbfa12a 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -29,6 +29,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/toast/toast.h" #include "ui/buttons/history_down_button.h" #include "inline_bots/inline_bot_result.h" +#include "data/data_drafts.h" #include "lang.h" #include "application.h" #include "mainwidget.h" @@ -99,8 +100,6 @@ HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, His , _history(history) , _widget(historyWidget) , _scroll(scroll) { - connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); - _touchSelectTimer.setSingleShot(true); connect(&_touchSelectTimer, SIGNAL(timeout()), this, SLOT(onTouchSelect())); @@ -2838,7 +2837,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) setAcceptDrops(true); - connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(updateField())); + connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(&_reportSpamPanel, SIGNAL(reportClicked()), this, SLOT(onReportSpamClicked())); connect(&_reportSpamPanel, SIGNAL(hideClicked()), this, SLOT(onReportSpamHide())); @@ -3128,10 +3127,10 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() { if (!_history) return; if (_editMsgId) { - _history->setEditDraft(std_::make_unique(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId)); + _history->setEditDraft(std_::make_unique(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId)); } else { if (_replyToId || !_field.isEmpty()) { - _history->setLocalDraft(std_::make_unique(_field, _replyToId, _previewCancelled)); + _history->setLocalDraft(std_::make_unique(_field, _replyToId, _previewCancelled)); } else { _history->clearLocalDraft(); } @@ -3145,8 +3144,8 @@ void HistoryWidget::onCloudDraftSave() { } } -void HistoryWidget::writeDrafts(HistoryDraft **localDraft, HistoryDraft **editDraft) { - HistoryDraft *historyLocalDraft = _history ? _history->localDraft() : nullptr; +void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraft) { + Data::Draft *historyLocalDraft = _history ? _history->localDraft() : nullptr; if (!localDraft && _editMsgId) localDraft = &historyLocalDraft; bool save = _peer && (_saveDraftStart > 0); @@ -3203,21 +3202,6 @@ void HistoryWidget::writeDrafts(HistoryDraft **localDraft, HistoryDraft **editDr } } -void HistoryWidget::writeDrafts(History *history) { - Local::MessageDraft storedLocalDraft, storedEditDraft; - MessageCursor localCursor, editCursor; - if (auto localDraft = history->localDraft()) { - storedLocalDraft = Local::MessageDraft(localDraft->msgId, localDraft->textWithTags, localDraft->previewCancelled); - localCursor = localDraft->cursor; - } - if (auto editDraft = history->editDraft()) { - storedEditDraft = Local::MessageDraft(editDraft->msgId, editDraft->textWithTags, editDraft->previewCancelled); - editCursor = editDraft->cursor; - } - Local::writeDrafts(history->peer->id, storedLocalDraft, storedEditDraft); - Local::writeDraftCursors(history->peer->id, localCursor, editCursor); -} - void HistoryWidget::cancelSendAction(History *history, SendActionType type) { QMap, mtpRequestId>::iterator i = _sendActionRequests.find(qMakePair(history, type)); if (i != _sendActionRequests.cend()) { @@ -3388,7 +3372,7 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query) { History *h = App::history(toPeerId); TextWithTags textWithTags = { '@' + bot->username + ' ' + query, TextWithTags::Tags() }; MessageCursor cursor = { textWithTags.text.size(), textWithTags.text.size(), QFIXED_MAX }; - h->setLocalDraft(std_::make_unique(textWithTags, 0, cursor, false)); + h->setLocalDraft(std_::make_unique(textWithTags, 0, cursor, false)); if (h == _history) { applyDraft(); } else { @@ -3679,10 +3663,11 @@ void HistoryWidget::fastShowAtEnd(History *h) { } void HistoryWidget::applyDraft(bool parseLinks) { - HistoryDraft *draft = _history ? _history->draft() : nullptr; + auto draft = _history ? _history->draft() : nullptr; if (!draft) { clearFieldText(); _field.setFocus(); + _replyEditMsg = nullptr; _editMsgId = _replyToId = 0; return; } @@ -3693,6 +3678,7 @@ void HistoryWidget::applyDraft(bool parseLinks) { draft->cursor.applyTo(_field); _textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping; _previewCancelled = draft->previewCancelled; + _replyEditMsg = nullptr; if (auto editDraft = _history->editDraft()) { _editMsgId = editDraft->msgId; _replyToId = 0; @@ -3700,6 +3686,7 @@ void HistoryWidget::applyDraft(bool parseLinks) { _editMsgId = 0; _replyToId = readyToForward() ? 0 : _history->localDraft()->msgId; } + if (parseLinks) { onPreviewParse(); } @@ -3784,10 +3771,6 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re _migrated->clearEditDraft(); } - auto localDraft = _history->localDraft(); - auto editDraft = _history->editDraft(); - writeDrafts(&localDraft, &editDraft); - _history->showAtMsgId = _showAtMsgId; destroyUnreadBar(); @@ -3797,10 +3780,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re } _addToScroll = 0; - _editMsgId = 0; _saveEditMsgRequestId = 0; - _replyToId = 0; - _replyEditMsg = 0; + _replyEditMsg = nullptr; + _editMsgId = _replyToId = 0; _previewData = 0; _previewCache.clear(); _fieldBarCancel.hide(); @@ -4173,14 +4155,12 @@ void HistoryWidget::updateControlsVisibility() { } else if (_canSendMessages) { onCheckFieldAutocomplete(); if (isBotStart()) { - if (isBotStart()) { - _unblock.hide(); - _joinChannel.hide(); - _muteUnmute.hide(); - if (_botStart.isHidden()) { - _botStart.clearState(); - _botStart.show(); - } + _unblock.hide(); + _joinChannel.hide(); + _muteUnmute.hide(); + if (_botStart.isHidden()) { + _botStart.clearState(); + _botStart.show(); } _kbShown = false; _send.hide(); @@ -4773,7 +4753,7 @@ void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, if (auto editDraft = history->editDraft()) { if (editDraft->saveRequestId == req) { history->clearEditDraft(); - writeDrafts(history); + if (App::main()) App::main()->writeDrafts(history); } } } @@ -5407,7 +5387,7 @@ bool HistoryWidget::botCallbackFail(BotCallbackInfo info, const RPCError &error, } bool HistoryWidget::insertBotCommand(const QString &cmd, bool specialGif) { - if (!_history) return false; + if (!_history || !_canSendMessages) return false; bool insertingInlineBot = !cmd.isEmpty() && (cmd.at(0) == '@'); QString toInsert = cmd; @@ -7266,7 +7246,7 @@ void HistoryWidget::onReplyToMessage() { if (auto localDraft = _history->localDraft()) { localDraft->msgId = to->id; } else { - _history->setLocalDraft(std_::make_unique(TextWithTags(), to->id, MessageCursor(), false)); + _history->setLocalDraft(std_::make_unique(TextWithTags(), to->id, MessageCursor(), false)); } } else { _replyEditMsg = to; @@ -7299,10 +7279,12 @@ void HistoryWidget::onEditMessage() { } else { delete box; - if (_replyToId || !_field.isEmpty()) { - _history->setLocalDraft(std_::make_unique(_field, _replyToId, _previewCancelled)); - } else { - _history->clearLocalDraft(); + if (!_editMsgId) { + if (_replyToId || !_field.isEmpty()) { + _history->setLocalDraft(std_::make_unique(_field, _replyToId, _previewCancelled)); + } else { + _history->clearLocalDraft(); + } } auto original = to->originalText(); @@ -7310,7 +7292,7 @@ void HistoryWidget::onEditMessage() { auto editTags = textTagsFromEntities(original.entities); TextWithTags editData = { editText, editTags }; MessageCursor cursor = { editText.size(), editText.size(), QFIXED_MAX }; - _history->setEditDraft(std_::make_unique(editData, to->id, cursor, false)); + _history->setEditDraft(std_::make_unique(editData, to->id, cursor, false)); applyDraft(false); _previewData = nullptr; @@ -7411,11 +7393,11 @@ bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const { } void HistoryWidget::cancelReply(bool lastKeyboardUsed) { - bool wasReply = false; ; + bool wasReply = false; if (_replyToId) { wasReply = true; - _replyEditMsg = 0; + _replyEditMsg = nullptr; _replyToId = 0; mouseMoveEvent(0); if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_kbReplyTo) { @@ -7451,8 +7433,8 @@ void HistoryWidget::cancelReply(bool lastKeyboardUsed) { void HistoryWidget::cancelEdit() { if (!_editMsgId) return; - _editMsgId = 0; _replyEditMsg = nullptr; + _editMsgId = 0; _history->clearEditDraft(); applyDraft(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 2847bf694..863b1100c 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -973,7 +973,7 @@ private: Q_DECLARE_FLAGS(TextUpdateEvents, TextUpdateEvent); Q_DECLARE_FRIEND_OPERATORS_FOR_FLAGS(TextUpdateEvents); - void writeDrafts(HistoryDraft **localDraft, HistoryDraft **editDraft); + void writeDrafts(Data::Draft **localDraft, Data::Draft **editDraft); void writeDrafts(History *history); void setFieldText(const TextWithTags &textWithTags, TextUpdateEvents events = 0, FlatTextarea::UndoHistoryAction undoHistoryAction = FlatTextarea::ClearUndoHistory); void clearFieldText(TextUpdateEvents events = 0, FlatTextarea::UndoHistoryAction undoHistoryAction = FlatTextarea::ClearUndoHistory) { diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 859af987b..51c1d1487 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "serialize/serialize_document.h" #include "serialize/serialize_common.h" +#include "data/data_drafts.h" #include "observer_peer.h" #include "mainwidget.h" #include "mainwindow.h" @@ -2409,13 +2410,13 @@ namespace Local { if (msgData.text.isEmpty() && !msgReplyTo) { h->clearLocalDraft(); } else { - h->setLocalDraft(std_::make_unique(msgData, msgReplyTo, msgCursor, msgPreviewCancelled)); + h->setLocalDraft(std_::make_unique(msgData, msgReplyTo, msgCursor, msgPreviewCancelled)); } } if (!editMsgId) { h->clearEditDraft(); } else { - h->setEditDraft(std_::make_unique(editData, editMsgId, editCursor, editPreviewCancelled)); + h->setEditDraft(std_::make_unique(editData, editMsgId, editCursor, editPreviewCancelled)); } } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 23bfe1ccb..e59b115fd 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -174,7 +174,7 @@ bool MainWidget::onShareUrl(const PeerId &peer, const QString &url, const QStrin History *h = App::history(peer); TextWithTags textWithTags = { url + '\n' + text, TextWithTags::Tags() }; MessageCursor cursor = { url.size() + 1, url.size() + 1 + text.size(), QFIXED_MAX }; - h->setLocalDraft(std_::make_unique(textWithTags, 0, cursor, false)); + h->setLocalDraft(std_::make_unique(textWithTags, 0, cursor, false)); h->clearEditDraft(); bool opened = _history->peer() && (_history->peer()->id == peer); if (opened) { @@ -194,7 +194,7 @@ bool MainWidget::onInlineSwitchChosen(const PeerId &peer, const QString &botAndQ History *h = App::history(peer); TextWithTags textWithTags = { botAndQuery, TextWithTags::Tags() }; MessageCursor cursor = { botAndQuery.size(), botAndQuery.size(), QFIXED_MAX }; - h->setLocalDraft(std_::make_unique(textWithTags, 0, cursor, false)); + h->setLocalDraft(std_::make_unique(textWithTags, 0, cursor, false)); h->clearEditDraft(); bool opened = _history->peer() && (_history->peer()->id == peer); if (opened) { @@ -3772,9 +3772,11 @@ void MainWidget::saveDraftToCloud() { auto peer = _history->peer(); if (auto history = App::historyLoaded(peer)) { + writeDrafts(history); + auto localDraft = history->localDraft(); auto cloudDraft = history->cloudDraft(); - if (!historyDraftsAreEqual(localDraft, cloudDraft)) { + if (!Data::draftsAreEqual(localDraft, cloudDraft)) { App::api()->saveDraftToCloudDelayed(history); } } @@ -3784,6 +3786,23 @@ void MainWidget::applyCloudDraft(History *history) { _history->applyCloudDraft(history); } +void MainWidget::writeDrafts(History *history) { + Local::MessageDraft storedLocalDraft, storedEditDraft; + MessageCursor localCursor, editCursor; + if (auto localDraft = history->localDraft()) { + if (!Data::draftsAreEqual(localDraft, history->cloudDraft())) { + storedLocalDraft = Local::MessageDraft(localDraft->msgId, localDraft->textWithTags, localDraft->previewCancelled); + localCursor = localDraft->cursor; + } + } + if (auto editDraft = history->editDraft()) { + storedEditDraft = Local::MessageDraft(editDraft->msgId, editDraft->textWithTags, editDraft->previewCancelled); + editCursor = editDraft->cursor; + } + Local::writeDrafts(history->peer->id, storedLocalDraft, storedEditDraft); + Local::writeDraftCursors(history->peer->id, localCursor, editCursor); +} + void MainWidget::checkIdleFinish() { if (this != App::main()) return; if (psIdleTime() < uint64(Global::OfflineIdleTimeout())) { @@ -4668,6 +4687,8 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { if (draftMessage.type() == mtpc_draftMessage) { auto &draft = draftMessage.c_draftMessage(); Data::applyPeerCloudDraft(peerId, draft); + } else { + Data::clearPeerCloudDraft(peerId); } } break; diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 8348fd2e6..52e49beb9 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -241,6 +241,7 @@ public: void saveDraftToCloud(); void applyCloudDraft(History *history); + void writeDrafts(History *history); int32 dlgsWidth() const; diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index 4ac4b298a..98437d307 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -1869,7 +1869,6 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-fstdafx.h" "-f../../SourceFiles/ui/twidget.h" - diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters index cc4995b6b..f683c4582 100644 --- a/Telegram/Telegram.vcxproj.filters +++ b/Telegram/Telegram.vcxproj.filters @@ -1520,9 +1520,6 @@ SourceFiles\history - - SourceFiles\ui\style - SourceFiles\data