Cloud draft handling improved. Fixed Edit while already editing a msg.

This commit is contained in:
John Preston 2016-06-09 17:31:10 +03:00
parent 19cacd0efb
commit a428534345
14 changed files with 197 additions and 145 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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<HistoryDraft>(textWithTags, replyTo, MessageCursor(QFIXED_MAX, QFIXED_MAX, QFIXED_MAX), draft.is_no_webpage());
auto cloudDraft = std_::make_unique<Draft>(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

View File

@ -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

View File

@ -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 <typename PaintItemCallback>
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;

View File

@ -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<Data::Draft> &&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<HistoryDraft>(draft->textWithTags, draft->msgId, draft->cursor, draft->previewCancelled));
setLocalDraft(std_::make_unique<Data::Draft>(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<HistoryDraft>(TextWithTags(), 0, MessageCursor(), false));
void History::setCloudDraft(std_::unique_ptr<Data::Draft> &&draft) {
_cloudDraft = std_::move(draft);
cloudDraftTextCache.clear();
}
Data::Draft *History::createCloudDraft(Data::Draft *fromDraft) {
if (Data::draftIsNull(fromDraft)) {
setCloudDraft(std_::make_unique<Data::Draft>(TextWithTags(), 0, MessageCursor(), false));
cloudDraft()->date = QDateTime();
} else {
auto existing = cloudDraft();
if (!existing) {
setCloudDraft(std_::make_unique<HistoryDraft>(fromDraft->textWithTags, fromDraft->msgId, fromDraft->cursor, fromDraft->previewCancelled));
setCloudDraft(std_::make_unique<Data::Draft>(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<Data::Draft> &&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;) {

View File

@ -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<HistoryItem*> 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<HistoryDraft> &&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<Data::Draft> &&draft);
void takeLocalDraft(History *from);
void createLocalDraftFromCloud();
void setCloudDraft(std_::unique_ptr<HistoryDraft> &&draft) {
_cloudDraft = std_::move(draft);
cloudDraftTextCache.clear();
}
HistoryDraft *createCloudDraft(HistoryDraft *fromDraft);
void setEditDraft(std_::unique_ptr<HistoryDraft> &&draft) {
_editDraft = std_::move(draft);
}
void clearLocalDraft() {
_localDraft = nullptr;
}
void setCloudDraft(std_::unique_ptr<Data::Draft> &&draft);
Data::Draft *createCloudDraft(Data::Draft *fromDraft);
void setEditDraft(std_::unique_ptr<Data::Draft> &&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<HistoryDraft> _localDraft, _cloudDraft;
std_::unique_ptr<HistoryDraft> _editDraft;
std_::unique_ptr<Data::Draft> _localDraft, _cloudDraft;
std_::unique_ptr<Data::Draft> _editDraft;
};

View File

@ -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<HistoryDraft>(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId));
_history->setEditDraft(std_::make_unique<Data::Draft>(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId));
} else {
if (_replyToId || !_field.isEmpty()) {
_history->setLocalDraft(std_::make_unique<HistoryDraft>(_field, _replyToId, _previewCancelled));
_history->setLocalDraft(std_::make_unique<Data::Draft>(_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<QPair<History*, SendActionType>, 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<HistoryDraft>(textWithTags, 0, cursor, false));
h->setLocalDraft(std_::make_unique<Data::Draft>(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<HistoryDraft>(TextWithTags(), to->id, MessageCursor(), false));
_history->setLocalDraft(std_::make_unique<Data::Draft>(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<HistoryDraft>(_field, _replyToId, _previewCancelled));
} else {
_history->clearLocalDraft();
if (!_editMsgId) {
if (_replyToId || !_field.isEmpty()) {
_history->setLocalDraft(std_::make_unique<Data::Draft>(_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<HistoryDraft>(editData, to->id, cursor, false));
_history->setEditDraft(std_::make_unique<Data::Draft>(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();

View File

@ -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) {

View File

@ -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<HistoryDraft>(msgData, msgReplyTo, msgCursor, msgPreviewCancelled));
h->setLocalDraft(std_::make_unique<Data::Draft>(msgData, msgReplyTo, msgCursor, msgPreviewCancelled));
}
}
if (!editMsgId) {
h->clearEditDraft();
} else {
h->setEditDraft(std_::make_unique<HistoryDraft>(editData, editMsgId, editCursor, editPreviewCancelled));
h->setEditDraft(std_::make_unique<Data::Draft>(editData, editMsgId, editCursor, editPreviewCancelled));
}
}

View File

@ -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<HistoryDraft>(textWithTags, 0, cursor, false));
h->setLocalDraft(std_::make_unique<Data::Draft>(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<HistoryDraft>(textWithTags, 0, cursor, false));
h->setLocalDraft(std_::make_unique<Data::Draft>(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;

View File

@ -241,6 +241,7 @@ public:
void saveDraftToCloud();
void applyCloudDraft(History *history);
void writeDrafts(History *history);
int32 dlgsWidth() const;

View File

@ -1869,7 +1869,6 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(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"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\ui\style\style_abstract_data.h" />
<ClInclude Include="SourceFiles\ui\style\style_core.h" />
<ClInclude Include="SourceFiles\ui\style\style_core_color.h" />
<ClInclude Include="SourceFiles\ui\style\style_core_font.h" />

View File

@ -1520,9 +1520,6 @@
<ClInclude Include="SourceFiles\history\history_service_layout.h">
<Filter>SourceFiles\history</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\ui\style\style_abstract_data.h">
<Filter>SourceFiles\ui\style</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\data\data_abstract_structure.h">
<Filter>SourceFiles\data</Filter>
</ClInclude>