Update API scheme, rich preview drafts.
This commit is contained in:
parent
b2e8e0431e
commit
b1823d981b
|
@ -2135,8 +2135,10 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
|
|
||||||
auto flags = MTPmessages_SaveDraft::Flags(0);
|
auto flags = MTPmessages_SaveDraft::Flags(0);
|
||||||
auto &textWithTags = cloudDraft->textWithTags;
|
auto &textWithTags = cloudDraft->textWithTags;
|
||||||
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
|
if (cloudDraft->webpage.removed) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
||||||
|
} 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) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_reply_to;
|
flags |= MTPmessages_SaveDraft::Flag::f_reply_to;
|
||||||
|
@ -2149,6 +2151,7 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||||
Api::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
|
using PageFlag = MTPDinputMediaWebPage::Flag;
|
||||||
history->startSavingCloudDraft(topicRootId);
|
history->startSavingCloudDraft(topicRootId);
|
||||||
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
|
@ -2156,7 +2159,15 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
history->peer->input,
|
history->peer->input,
|
||||||
MTP_string(textWithTags.text),
|
MTP_string(textWithTags.text),
|
||||||
entities,
|
entities,
|
||||||
MTPInputMedia()
|
MTP_inputMediaWebPage(
|
||||||
|
MTP_flags(PageFlag::f_optional
|
||||||
|
| (cloudDraft->webpage.forceLargeMedia
|
||||||
|
? PageFlag::f_force_large_media
|
||||||
|
: PageFlag())
|
||||||
|
| (cloudDraft->webpage.forceSmallMedia
|
||||||
|
? PageFlag::f_force_small_media
|
||||||
|
: PageFlag())),
|
||||||
|
MTP_string(cloudDraft->webpage.url))
|
||||||
)).done([=](const MTPBool &result, const MTP::Response &response) {
|
)).done([=](const MTPBool &result, const MTP::Response &response) {
|
||||||
const auto requestId = response.requestId;
|
const auto requestId = response.requestId;
|
||||||
history->finishSavingCloudDraft(
|
history->finishSavingCloudDraft(
|
||||||
|
@ -2243,7 +2254,7 @@ void ApiWrap::gotStickerSet(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::requestWebPageDelayed(not_null<WebPageData*> page) {
|
void ApiWrap::requestWebPageDelayed(not_null<WebPageData*> page) {
|
||||||
if (page->pendingTill <= 0) {
|
if (page->failed || !page->pendingTill) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_webPagesPending.emplace(page, 0);
|
_webPagesPending.emplace(page, 0);
|
||||||
|
@ -2548,7 +2559,8 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &resu
|
||||||
for (auto i = _webPagesPending.begin(); i != _webPagesPending.cend();) {
|
for (auto i = _webPagesPending.begin(); i != _webPagesPending.cend();) {
|
||||||
if (i->second == req) {
|
if (i->second == req) {
|
||||||
if (i->first->pendingTill > 0) {
|
if (i->first->pendingTill > 0) {
|
||||||
i->first->pendingTill = -1;
|
i->first->pendingTill = 0;
|
||||||
|
i->first->failed = 1;
|
||||||
_session->data().notifyWebPageUpdateDelayed(i->first);
|
_session->data().notifyWebPageUpdateDelayed(i->first);
|
||||||
}
|
}
|
||||||
i = _webPagesPending.erase(i);
|
i = _webPagesPending.erase(i);
|
||||||
|
|
|
@ -15,33 +15,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_web_page.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
WebPageDraft WebPageDraft::FromItem(not_null<HistoryItem*> item) {
|
||||||
|
const auto previewMedia = item->media();
|
||||||
|
const auto previewPage = previewMedia
|
||||||
|
? previewMedia->webpage()
|
||||||
|
: nullptr;
|
||||||
|
using PageFlag = MediaWebPageFlag;
|
||||||
|
const auto previewFlags = previewMedia
|
||||||
|
? previewMedia->webpageFlags()
|
||||||
|
: PageFlag();
|
||||||
|
return {
|
||||||
|
.id = previewPage ? previewPage->id : 0,
|
||||||
|
.url = previewPage ? previewPage->url : QString(),
|
||||||
|
.forceLargeMedia = !!(previewFlags & PageFlag::ForceLargeMedia),
|
||||||
|
.forceSmallMedia = !!(previewFlags & PageFlag::ForceSmallMedia),
|
||||||
|
.invert = item->invertMedia(),
|
||||||
|
.manual = !!(previewFlags & PageFlag::Manual),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Draft::Draft(
|
Draft::Draft(
|
||||||
const TextWithTags &textWithTags,
|
const TextWithTags &textWithTags,
|
||||||
FullReplyTo reply,
|
FullReplyTo reply,
|
||||||
const MessageCursor &cursor,
|
const MessageCursor &cursor,
|
||||||
PreviewState previewState,
|
WebPageDraft webpage,
|
||||||
mtpRequestId saveRequestId)
|
mtpRequestId saveRequestId)
|
||||||
: textWithTags(textWithTags)
|
: textWithTags(textWithTags)
|
||||||
, reply(std::move(reply))
|
, reply(std::move(reply))
|
||||||
, cursor(cursor)
|
, cursor(cursor)
|
||||||
, previewState(previewState)
|
, webpage(webpage)
|
||||||
, saveRequestId(saveRequestId) {
|
, saveRequestId(saveRequestId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Draft::Draft(
|
Draft::Draft(
|
||||||
not_null<const Ui::InputField*> field,
|
not_null<const Ui::InputField*> field,
|
||||||
FullReplyTo reply,
|
FullReplyTo reply,
|
||||||
PreviewState previewState,
|
WebPageDraft webpage,
|
||||||
mtpRequestId saveRequestId)
|
mtpRequestId saveRequestId)
|
||||||
: textWithTags(field->getTextWithTags())
|
: textWithTags(field->getTextWithTags())
|
||||||
, reply(std::move(reply))
|
, reply(std::move(reply))
|
||||||
, cursor(field)
|
, cursor(field)
|
||||||
, previewState(previewState) {
|
, webpage(webpage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyPeerCloudDraft(
|
void ApplyPeerCloudDraft(
|
||||||
|
@ -67,6 +87,23 @@ void ApplyPeerCloudDraft(
|
||||||
const auto replyPeerId = reply.externalPeerId
|
const auto replyPeerId = reply.externalPeerId
|
||||||
? reply.externalPeerId
|
? reply.externalPeerId
|
||||||
: peerId;
|
: peerId;
|
||||||
|
auto webpage = WebPageDraft{
|
||||||
|
.invert = draft.is_invert_media(),
|
||||||
|
.removed = draft.is_no_webpage(),
|
||||||
|
};
|
||||||
|
if (const auto media = draft.vmedia()) {
|
||||||
|
media->match([&](const MTPDmessageMediaWebPage &data) {
|
||||||
|
const auto parsed = session->data().processWebpage(
|
||||||
|
data.vwebpage());
|
||||||
|
if (!parsed->failed) {
|
||||||
|
webpage.forceLargeMedia = data.is_force_large_media();
|
||||||
|
webpage.forceSmallMedia = data.is_force_small_media();
|
||||||
|
webpage.manual = data.is_manual();
|
||||||
|
webpage.url = parsed->url;
|
||||||
|
webpage.id = parsed->id;
|
||||||
|
}
|
||||||
|
}, [](const auto &) {});
|
||||||
|
}
|
||||||
auto cloudDraft = std::make_unique<Draft>(
|
auto cloudDraft = std::make_unique<Draft>(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
FullReplyTo{
|
FullReplyTo{
|
||||||
|
@ -78,9 +115,7 @@ void ApplyPeerCloudDraft(
|
||||||
.topicRootId = topicRootId,
|
.topicRootId = topicRootId,
|
||||||
},
|
},
|
||||||
MessageCursor(Ui::kQFixedMax, Ui::kQFixedMax, Ui::kQFixedMax),
|
MessageCursor(Ui::kQFixedMax, Ui::kQFixedMax, Ui::kQFixedMax),
|
||||||
(draft.is_no_webpage()
|
std::move(webpage));
|
||||||
? Data::PreviewState::Cancelled
|
|
||||||
: Data::PreviewState::Allowed));
|
|
||||||
cloudDraft->date = date;
|
cloudDraft->date = date;
|
||||||
|
|
||||||
history->setCloudDraft(std::move(cloudDraft));
|
history->setCloudDraft(std::move(cloudDraft));
|
||||||
|
|
|
@ -30,10 +30,19 @@ void ClearPeerCloudDraft(
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
TimeId date);
|
TimeId date);
|
||||||
|
|
||||||
enum class PreviewState : char {
|
struct WebPageDraft {
|
||||||
Allowed,
|
[[nodiscard]] static WebPageDraft FromItem(not_null<HistoryItem*> item);
|
||||||
Cancelled,
|
|
||||||
EmptyOnEdit,
|
WebPageId id = 0;
|
||||||
|
QString url;
|
||||||
|
bool forceLargeMedia : 1 = false;
|
||||||
|
bool forceSmallMedia : 1 = false;
|
||||||
|
bool invert : 1 = false;
|
||||||
|
bool manual : 1 = false;
|
||||||
|
bool removed : 1 = false;
|
||||||
|
|
||||||
|
friend inline bool operator==(const WebPageDraft&, const WebPageDraft&)
|
||||||
|
= default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Draft {
|
struct Draft {
|
||||||
|
@ -42,19 +51,19 @@ struct Draft {
|
||||||
const TextWithTags &textWithTags,
|
const TextWithTags &textWithTags,
|
||||||
FullReplyTo reply,
|
FullReplyTo reply,
|
||||||
const MessageCursor &cursor,
|
const MessageCursor &cursor,
|
||||||
PreviewState previewState,
|
WebPageDraft webpage,
|
||||||
mtpRequestId saveRequestId = 0);
|
mtpRequestId saveRequestId = 0);
|
||||||
Draft(
|
Draft(
|
||||||
not_null<const Ui::InputField*> field,
|
not_null<const Ui::InputField*> field,
|
||||||
FullReplyTo reply,
|
FullReplyTo reply,
|
||||||
PreviewState previewState,
|
WebPageDraft webpage,
|
||||||
mtpRequestId saveRequestId = 0);
|
mtpRequestId saveRequestId = 0);
|
||||||
|
|
||||||
TimeId date = 0;
|
TimeId date = 0;
|
||||||
TextWithTags textWithTags;
|
TextWithTags textWithTags;
|
||||||
FullReplyTo reply; // reply.messageId.msg is editMsgId for edit draft.
|
FullReplyTo reply; // reply.messageId.msg is editMsgId for edit draft.
|
||||||
MessageCursor cursor;
|
MessageCursor cursor;
|
||||||
PreviewState previewState = PreviewState::Allowed;
|
WebPageDraft webpage;
|
||||||
mtpRequestId saveRequestId = 0;
|
mtpRequestId saveRequestId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,7 +189,7 @@ using HistoryDrafts = base::flat_map<DraftKey, std::unique_ptr<Draft>>;
|
||||||
}
|
}
|
||||||
return (a->textWithTags == b->textWithTags)
|
return (a->textWithTags == b->textWithTags)
|
||||||
&& (a->reply == b->reply)
|
&& (a->reply == b->reply)
|
||||||
&& (a->previewState == b->previewState);
|
&& (a->webpage == b->webpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -404,6 +404,10 @@ WebPageData *Media::webpage() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaWebPageFlags Media::webpageFlags() const {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const SharedContact *Media::sharedContact() const {
|
const SharedContact *Media::sharedContact() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1462,6 +1466,10 @@ WebPageData *MediaWebPage::webpage() const {
|
||||||
return _page;
|
return _page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaWebPageFlags MediaWebPage::webpageFlags() const {
|
||||||
|
return _flags;
|
||||||
|
}
|
||||||
|
|
||||||
bool MediaWebPage::hasReplyPreview() const {
|
bool MediaWebPage::hasReplyPreview() const {
|
||||||
if (const auto document = MediaWebPage::document()) {
|
if (const auto document = MediaWebPage::document()) {
|
||||||
return document->hasThumbnail()
|
return document->hasThumbnail()
|
||||||
|
|
|
@ -122,6 +122,7 @@ public:
|
||||||
virtual DocumentData *document() const;
|
virtual DocumentData *document() const;
|
||||||
virtual PhotoData *photo() const;
|
virtual PhotoData *photo() const;
|
||||||
virtual WebPageData *webpage() const;
|
virtual WebPageData *webpage() const;
|
||||||
|
virtual MediaWebPageFlags webpageFlags() const;
|
||||||
virtual const SharedContact *sharedContact() const;
|
virtual const SharedContact *sharedContact() const;
|
||||||
virtual const Call *call() const;
|
virtual const Call *call() const;
|
||||||
virtual GameData *game() const;
|
virtual GameData *game() const;
|
||||||
|
@ -381,6 +382,7 @@ public:
|
||||||
DocumentData *document() const override;
|
DocumentData *document() const override;
|
||||||
PhotoData *photo() const override;
|
PhotoData *photo() const override;
|
||||||
WebPageData *webpage() const override;
|
WebPageData *webpage() const override;
|
||||||
|
MediaWebPageFlags webpageFlags() const override;
|
||||||
|
|
||||||
bool hasReplyPreview() const override;
|
bool hasReplyPreview() const override;
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
|
|
|
@ -3261,7 +3261,8 @@ not_null<WebPageData*> Session::processWebpage(const MTPWebPage &data) {
|
||||||
case mtpc_webPageEmpty: {
|
case mtpc_webPageEmpty: {
|
||||||
const auto result = webpage(data.c_webPageEmpty().vid().v);
|
const auto result = webpage(data.c_webPageEmpty().vid().v);
|
||||||
if (result->pendingTill > 0) {
|
if (result->pendingTill > 0) {
|
||||||
result->pendingTill = -1; // failed
|
result->pendingTill = 0;
|
||||||
|
result->failed = 1;
|
||||||
notifyWebPageUpdateDelayed(result);
|
notifyWebPageUpdateDelayed(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -227,7 +227,7 @@ bool WebPageData::applyChanges(
|
||||||
const QString &newAuthor,
|
const QString &newAuthor,
|
||||||
int newPendingTill) {
|
int newPendingTill) {
|
||||||
if (newPendingTill != 0
|
if (newPendingTill != 0
|
||||||
&& (!url.isEmpty() || pendingTill < 0)
|
&& (!url.isEmpty() || failed)
|
||||||
&& (!pendingTill
|
&& (!pendingTill
|
||||||
|| pendingTill == newPendingTill
|
|| pendingTill == newPendingTill
|
||||||
|| newPendingTill < -1)) {
|
|| newPendingTill < -1)) {
|
||||||
|
|
|
@ -100,8 +100,9 @@ struct WebPageData {
|
||||||
DocumentData *document = nullptr;
|
DocumentData *document = nullptr;
|
||||||
WebPageCollage collage;
|
WebPageCollage collage;
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
int pendingTill = 0;
|
TimeId pendingTill = 0;
|
||||||
int version = 0;
|
uint32 version : 31 = 0;
|
||||||
|
uint32 failed : 1 = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void replaceDocumentGoodThumbnail();
|
void replaceDocumentGoodThumbnail();
|
||||||
|
|
|
@ -203,13 +203,13 @@ void History::createLocalDraftFromCloud(MsgId topicRootId) {
|
||||||
draft->textWithTags,
|
draft->textWithTags,
|
||||||
draft->reply,
|
draft->reply,
|
||||||
draft->cursor,
|
draft->cursor,
|
||||||
draft->previewState));
|
draft->webpage));
|
||||||
existing = localDraft(topicRootId);
|
existing = localDraft(topicRootId);
|
||||||
} else if (existing != draft) {
|
} else if (existing != draft) {
|
||||||
existing->textWithTags = draft->textWithTags;
|
existing->textWithTags = draft->textWithTags;
|
||||||
existing->reply = draft->reply;
|
existing->reply = draft->reply;
|
||||||
existing->cursor = draft->cursor;
|
existing->cursor = draft->cursor;
|
||||||
existing->previewState = draft->previewState;
|
existing->webpage = draft->webpage;
|
||||||
}
|
}
|
||||||
existing->date = draft->date;
|
existing->date = draft->date;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ Data::Draft *History::createCloudDraft(
|
||||||
TextWithTags(),
|
TextWithTags(),
|
||||||
FullReplyTo(),
|
FullReplyTo(),
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
Data::PreviewState::Allowed));
|
Data::WebPageDraft()));
|
||||||
cloudDraft(topicRootId)->date = TimeId(0);
|
cloudDraft(topicRootId)->date = TimeId(0);
|
||||||
} else {
|
} else {
|
||||||
auto existing = cloudDraft(topicRootId);
|
auto existing = cloudDraft(topicRootId);
|
||||||
|
@ -286,13 +286,13 @@ Data::Draft *History::createCloudDraft(
|
||||||
fromDraft->textWithTags,
|
fromDraft->textWithTags,
|
||||||
fromDraft->reply,
|
fromDraft->reply,
|
||||||
fromDraft->cursor,
|
fromDraft->cursor,
|
||||||
fromDraft->previewState));
|
fromDraft->webpage));
|
||||||
existing = cloudDraft(topicRootId);
|
existing = cloudDraft(topicRootId);
|
||||||
} else if (existing != fromDraft) {
|
} else if (existing != fromDraft) {
|
||||||
existing->textWithTags = fromDraft->textWithTags;
|
existing->textWithTags = fromDraft->textWithTags;
|
||||||
existing->reply = fromDraft->reply;
|
existing->reply = fromDraft->reply;
|
||||||
existing->cursor = fromDraft->cursor;
|
existing->cursor = fromDraft->cursor;
|
||||||
existing->previewState = fromDraft->previewState;
|
existing->webpage = fromDraft->webpage;
|
||||||
}
|
}
|
||||||
existing->date = base::unixtime::now();
|
existing->date = base::unixtime::now();
|
||||||
existing->reply.topicRootId = topicRootId;
|
existing->reply.topicRootId = topicRootId;
|
||||||
|
|
|
@ -206,7 +206,6 @@ HistoryWidget::HistoryWidget(
|
||||||
, _updateEditTimeLeftDisplay([=] { updateField(); })
|
, _updateEditTimeLeftDisplay([=] { updateField(); })
|
||||||
, _fieldBarCancel(this, st::historyReplyCancel)
|
, _fieldBarCancel(this, st::historyReplyCancel)
|
||||||
, _previewTimer([=] { requestPreview(); })
|
, _previewTimer([=] { requestPreview(); })
|
||||||
, _previewState(Data::PreviewState::Allowed)
|
|
||||||
, _topBar(this, controller)
|
, _topBar(this, controller)
|
||||||
, _scroll(
|
, _scroll(
|
||||||
this,
|
this,
|
||||||
|
@ -443,10 +442,6 @@ HistoryWidget::HistoryWidget(
|
||||||
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
|
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
|
||||||
_fieldLinksParser->list().changes(
|
_fieldLinksParser->list().changes(
|
||||||
) | rpl::start_with_next([=](QStringList &&parsed) {
|
) | rpl::start_with_next([=](QStringList &&parsed) {
|
||||||
if (_previewState == Data::PreviewState::EmptyOnEdit
|
|
||||||
&& _parsedLinks != parsed) {
|
|
||||||
_previewState = Data::PreviewState::Allowed;
|
|
||||||
}
|
|
||||||
_parsedLinks = std::move(parsed);
|
_parsedLinks = std::move(parsed);
|
||||||
checkPreview();
|
checkPreview();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
@ -1604,7 +1599,7 @@ void HistoryWidget::fieldChanged() {
|
||||||
|
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
if (!HasSendText(_field)) {
|
if (!HasSendText(_field)) {
|
||||||
_previewState = Data::PreviewState::Allowed;
|
_previewDraft = {};
|
||||||
_fieldIsEmpty = true;
|
_fieldIsEmpty = true;
|
||||||
} else if (_fieldIsEmpty) {
|
} else if (_fieldIsEmpty) {
|
||||||
_fieldIsEmpty = false;
|
_fieldIsEmpty = false;
|
||||||
|
@ -1668,14 +1663,14 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
||||||
.messageId = FullMsgId(_history->peer->id, _editMsgId),
|
.messageId = FullMsgId(_history->peer->id, _editMsgId),
|
||||||
.topicRootId = topicRootId,
|
.topicRootId = topicRootId,
|
||||||
},
|
},
|
||||||
_previewState,
|
_previewDraft,
|
||||||
_saveEditMsgRequestId));
|
_saveEditMsgRequestId));
|
||||||
} else {
|
} else {
|
||||||
if (_replyTo || !_field->empty()) {
|
if (_replyTo || !_field->empty()) {
|
||||||
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||||
_field,
|
_field,
|
||||||
_replyTo,
|
_replyTo,
|
||||||
_previewState));
|
_previewDraft));
|
||||||
} else {
|
} else {
|
||||||
_history->clearLocalDraft(topicRootId);
|
_history->clearLocalDraft(topicRootId);
|
||||||
}
|
}
|
||||||
|
@ -1783,7 +1778,7 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
FullReplyTo(),
|
FullReplyTo(),
|
||||||
cursor,
|
cursor,
|
||||||
Data::PreviewState::Allowed));
|
Data::WebPageDraft()));
|
||||||
applyDraft();
|
applyDraft();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1935,7 +1930,7 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save links from _field to _parsedLinks without generating preview.
|
// Save links from _field to _parsedLinks without generating preview.
|
||||||
_previewState = Data::PreviewState::Cancelled;
|
_previewDraft = { .removed = true };
|
||||||
if (_editMsgId) {
|
if (_editMsgId) {
|
||||||
_fieldLinksParser->setDisabled(!_replyEditMsg
|
_fieldLinksParser->setDisabled(!_replyEditMsg
|
||||||
|| (_replyEditMsg->media()
|
|| (_replyEditMsg->media()
|
||||||
|
@ -1943,7 +1938,7 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
}
|
}
|
||||||
_fieldLinksParser->parseNow();
|
_fieldLinksParser->parseNow();
|
||||||
_parsedLinks = _fieldLinksParser->list().current();
|
_parsedLinks = _fieldLinksParser->list().current();
|
||||||
_previewState = draft->previewState;
|
_previewDraft = draft->webpage;
|
||||||
checkPreview();
|
checkPreview();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2471,7 +2466,7 @@ void HistoryWidget::registerDraftSource() {
|
||||||
? FullReplyTo{ FullMsgId(peerId, editMsgId) }
|
? FullReplyTo{ FullMsgId(peerId, editMsgId) }
|
||||||
: _replyTo),
|
: _replyTo),
|
||||||
_field->getTextWithTags(),
|
_field->getTextWithTags(),
|
||||||
_previewState,
|
_previewDraft,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
auto draftSource = Storage::MessageDraftSource{
|
auto draftSource = Storage::MessageDraftSource{
|
||||||
|
@ -2909,7 +2904,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
if (_editMsgId
|
if (_editMsgId
|
||||||
|| _replyTo
|
|| _replyTo
|
||||||
|| readyToForward()
|
|| readyToForward()
|
||||||
|| (_previewData && _previewData->pendingTill >= 0)
|
|| (_previewData && !_previewData->failed)
|
||||||
|| _kbReplyTo) {
|
|| _kbReplyTo) {
|
||||||
if (_fieldBarCancel->isHidden()) {
|
if (_fieldBarCancel->isHidden()) {
|
||||||
_fieldBarCancel->show();
|
_fieldBarCancel->show();
|
||||||
|
@ -3766,11 +3761,11 @@ void HistoryWidget::saveEditMsg() {
|
||||||
cancelEdit();
|
cancelEdit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
|
const auto webPageId = _previewDraft.removed
|
||||||
? CancelledWebPageId
|
? CancelledWebPageId
|
||||||
: ((_previewData && _previewData->pendingTill >= 0)
|
: (_previewData && !_previewData->failed)
|
||||||
? _previewData->id
|
? _previewData->id
|
||||||
: WebPageId(0));
|
: WebPageId();
|
||||||
|
|
||||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||||
const auto prepareFlags = Ui::ItemTextOptions(
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
|
@ -3925,11 +3920,11 @@ void HistoryWidget::send(Api::SendOptions options) {
|
||||||
_cornerButtons.clearReplyReturns();
|
_cornerButtons.clearReplyReturns();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
|
const auto webPageId = _previewDraft.removed
|
||||||
? CancelledWebPageId
|
? CancelledWebPageId
|
||||||
: ((_previewData && _previewData->pendingTill >= 0)
|
: (_previewData && !_previewData->failed)
|
||||||
? _previewData->id
|
? _previewData->id
|
||||||
: WebPageId(0));
|
: WebPageId();
|
||||||
|
|
||||||
auto message = Api::MessageToSend(prepareSendAction(options));
|
auto message = Api::MessageToSend(prepareSendAction(options));
|
||||||
message.textWithTags = _field->getTextWithAppliedMarkdown();
|
message.textWithTags = _field->getTextWithAppliedMarkdown();
|
||||||
|
@ -3950,7 +3945,9 @@ void HistoryWidget::send(Api::SendOptions options) {
|
||||||
|
|
||||||
hideSelectorControlsAnimated();
|
hideSelectorControlsAnimated();
|
||||||
|
|
||||||
if (_previewData && _previewData->pendingTill) previewCancel();
|
if (_previewData && _previewData->pendingTill) {
|
||||||
|
previewCancel();
|
||||||
|
}
|
||||||
setInnerFocus();
|
setInnerFocus();
|
||||||
|
|
||||||
if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) {
|
if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) {
|
||||||
|
@ -4790,7 +4787,10 @@ void HistoryWidget::toggleKeyboard(bool manual) {
|
||||||
_field->setMaxHeight(computeMaxFieldHeight());
|
_field->setMaxHeight(computeMaxFieldHeight());
|
||||||
|
|
||||||
_kbReplyTo = nullptr;
|
_kbReplyTo = nullptr;
|
||||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_editMsgId && !_replyTo) {
|
if (!readyToForward()
|
||||||
|
&& (!_previewData || _previewData->failed)
|
||||||
|
&& !_editMsgId
|
||||||
|
&& !_replyTo) {
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
}
|
}
|
||||||
|
@ -5775,7 +5775,10 @@ void HistoryWidget::updateHistoryGeometry(
|
||||||
} else if (writeRestriction().has_value()) {
|
} else if (writeRestriction().has_value()) {
|
||||||
newScrollHeight -= _unblock->height();
|
newScrollHeight -= _unblock->height();
|
||||||
}
|
}
|
||||||
if (_editMsgId || replyTo() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) {
|
if (_editMsgId
|
||||||
|
|| replyTo()
|
||||||
|
|| readyToForward()
|
||||||
|
|| (_previewData && !_previewData->failed)) {
|
||||||
newScrollHeight -= st::historyReplyHeight;
|
newScrollHeight -= st::historyReplyHeight;
|
||||||
}
|
}
|
||||||
if (_kbShown) {
|
if (_kbShown) {
|
||||||
|
@ -6077,7 +6080,9 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||||
_field->setMaxHeight(computeMaxFieldHeight());
|
_field->setMaxHeight(computeMaxFieldHeight());
|
||||||
_kbShown = false;
|
_kbShown = false;
|
||||||
_kbReplyTo = nullptr;
|
_kbReplyTo = nullptr;
|
||||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyTo) {
|
if (!readyToForward()
|
||||||
|
&& (!_previewData || _previewData->failed)
|
||||||
|
&& !_replyTo) {
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
}
|
}
|
||||||
|
@ -6093,7 +6098,10 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||||
_field->setMaxHeight(computeMaxFieldHeight());
|
_field->setMaxHeight(computeMaxFieldHeight());
|
||||||
_kbShown = false;
|
_kbShown = false;
|
||||||
_kbReplyTo = nullptr;
|
_kbReplyTo = nullptr;
|
||||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyTo && !_editMsgId) {
|
if (!readyToForward()
|
||||||
|
&& (!_previewData || _previewData->failed)
|
||||||
|
&& !_replyTo
|
||||||
|
&& !_editMsgId) {
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
}
|
}
|
||||||
|
@ -6138,7 +6146,7 @@ int HistoryWidget::computeMaxFieldHeight() const {
|
||||||
- ((_editMsgId
|
- ((_editMsgId
|
||||||
|| replyTo()
|
|| replyTo()
|
||||||
|| readyToForward()
|
|| readyToForward()
|
||||||
|| (_previewData && _previewData->pendingTill >= 0))
|
|| (_previewData && !_previewData->failed))
|
||||||
? st::historyReplyHeight
|
? st::historyReplyHeight
|
||||||
: 0)
|
: 0)
|
||||||
- (2 * st::historySendPadding)
|
- (2 * st::historySendPadding)
|
||||||
|
@ -6242,6 +6250,15 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
_peer,
|
_peer,
|
||||||
Window::SectionShow::Way::Forward,
|
Window::SectionShow::Way::Forward,
|
||||||
_editMsgId);
|
_editMsgId);
|
||||||
|
} else if (_previewData
|
||||||
|
&& !_previewData->failed
|
||||||
|
&& !_previewData->pendingTill) {
|
||||||
|
//const auto history = _history;
|
||||||
|
//using namespace HistoryView::Controls;
|
||||||
|
//EditWebPageOptions(
|
||||||
|
// controller()->uiShow(),
|
||||||
|
// _previewData,
|
||||||
|
// _previewDraft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7057,7 +7074,7 @@ void HistoryWidget::setFieldText(
|
||||||
| TextUpdateEvent::SendTyping;
|
| TextUpdateEvent::SendTyping;
|
||||||
|
|
||||||
previewCancel();
|
previewCancel();
|
||||||
_previewState = Data::PreviewState::Allowed;
|
_previewDraft = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::clearFieldText(
|
void HistoryWidget::clearFieldText(
|
||||||
|
@ -7171,7 +7188,7 @@ void HistoryWidget::setReplyFieldsFromProcessing() {
|
||||||
TextWithTags(),
|
TextWithTags(),
|
||||||
id,
|
id,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
Data::PreviewState::Allowed));
|
Data::WebPageDraft()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_replyEditMsg = item;
|
_replyEditMsg = item;
|
||||||
|
@ -7218,7 +7235,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
||||||
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||||
_field,
|
_field,
|
||||||
_replyTo,
|
_replyTo,
|
||||||
_previewState));
|
_previewDraft));
|
||||||
} else {
|
} else {
|
||||||
_history->clearLocalDraft({});
|
_history->clearLocalDraft({});
|
||||||
}
|
}
|
||||||
|
@ -7230,23 +7247,17 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
||||||
int(editData.text.size()),
|
int(editData.text.size()),
|
||||||
Ui::kQFixedMax
|
Ui::kQFixedMax
|
||||||
};
|
};
|
||||||
const auto previewPage = [&]() -> WebPageData* {
|
const auto previewDraft = Data::WebPageDraft::FromItem(item);
|
||||||
if (const auto media = item->media()) {
|
|
||||||
return media->webpage();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}();
|
|
||||||
const auto previewState = previewPage
|
|
||||||
? Data::PreviewState::Allowed
|
|
||||||
: Data::PreviewState::EmptyOnEdit;
|
|
||||||
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
||||||
editData,
|
editData,
|
||||||
FullReplyTo{ item->fullId() },
|
FullReplyTo{ item->fullId() },
|
||||||
cursor,
|
cursor,
|
||||||
previewState));
|
previewDraft));
|
||||||
applyDraft();
|
applyDraft();
|
||||||
|
|
||||||
_previewData = previewPage;
|
_previewData = previewDraft.id
|
||||||
|
? session().data().webpage(previewDraft.id).get()
|
||||||
|
: nullptr;
|
||||||
if (_previewData) {
|
if (_previewData) {
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
@ -7316,7 +7327,9 @@ bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
||||||
_processingReplyItem = _replyEditMsg = nullptr;
|
_processingReplyItem = _replyEditMsg = nullptr;
|
||||||
_processingReplyTo = _replyTo = FullReplyTo();
|
_processingReplyTo = _replyTo = FullReplyTo();
|
||||||
mouseMoveEvent(0);
|
mouseMoveEvent(0);
|
||||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_kbReplyTo) {
|
if (!readyToForward()
|
||||||
|
&& (!_previewData || _previewData->failed)
|
||||||
|
&& !_kbReplyTo) {
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
}
|
}
|
||||||
|
@ -7387,7 +7400,9 @@ void HistoryWidget::cancelEdit() {
|
||||||
saveDraft();
|
saveDraft();
|
||||||
|
|
||||||
mouseMoveEvent(nullptr);
|
mouseMoveEvent(nullptr);
|
||||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !replyTo()) {
|
if (!readyToForward()
|
||||||
|
&& (!_previewData || _previewData->failed)
|
||||||
|
&& !replyTo()) {
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
}
|
}
|
||||||
|
@ -7408,8 +7423,8 @@ void HistoryWidget::cancelEdit() {
|
||||||
void HistoryWidget::cancelFieldAreaState() {
|
void HistoryWidget::cancelFieldAreaState() {
|
||||||
controller()->hideLayer();
|
controller()->hideLayer();
|
||||||
_replyForwardPressed = false;
|
_replyForwardPressed = false;
|
||||||
if (_previewData && _previewData->pendingTill >= 0) {
|
if (_previewData && !_previewData->failed) {
|
||||||
_previewState = Data::PreviewState::Cancelled;
|
_previewDraft = { .removed = true };
|
||||||
previewCancel();
|
previewCancel();
|
||||||
|
|
||||||
_saveDraftText = true;
|
_saveDraftText = true;
|
||||||
|
@ -7437,7 +7452,7 @@ void HistoryWidget::checkPreview() {
|
||||||
const auto previewRestricted = [&] {
|
const auto previewRestricted = [&] {
|
||||||
return _peer && _peer->amRestricted(ChatRestriction::EmbedLinks);
|
return _peer && _peer->amRestricted(ChatRestriction::EmbedLinks);
|
||||||
}();
|
}();
|
||||||
if (_previewState != Data::PreviewState::Allowed || previewRestricted) {
|
if (_previewDraft.removed || previewRestricted) {
|
||||||
previewCancel();
|
previewCancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7446,7 +7461,7 @@ void HistoryWidget::checkPreview() {
|
||||||
_api.request(base::take(_previewRequest)).cancel();
|
_api.request(base::take(_previewRequest)).cancel();
|
||||||
_previewLinks = links;
|
_previewLinks = links;
|
||||||
if (_previewLinks.isEmpty()) {
|
if (_previewLinks.isEmpty()) {
|
||||||
if (_previewData && _previewData->pendingTill >= 0) {
|
if (_previewData && !_previewData->failed) {
|
||||||
previewCancel();
|
previewCancel();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -7462,7 +7477,7 @@ void HistoryWidget::checkPreview() {
|
||||||
} else if (i.value()) {
|
} else if (i.value()) {
|
||||||
_previewData = session().data().webpage(i.value());
|
_previewData = session().data().webpage(i.value());
|
||||||
updatePreview();
|
updatePreview();
|
||||||
} else if (_previewData && _previewData->pendingTill >= 0) {
|
} else if (_previewData && !_previewData->failed) {
|
||||||
previewCancel();
|
previewCancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7470,9 +7485,7 @@ void HistoryWidget::checkPreview() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::requestPreview() {
|
void HistoryWidget::requestPreview() {
|
||||||
if (!_previewData
|
if (!_previewData || _previewData->failed || _previewLinks.isEmpty()) {
|
||||||
|| (_previewData->pendingTill <= 0)
|
|
||||||
|| _previewLinks.isEmpty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto links = _previewLinks;
|
const auto links = _previewLinks;
|
||||||
|
@ -7498,11 +7511,11 @@ void HistoryWidget::gotPreview(
|
||||||
_previewCache.insert(links, page->id);
|
_previewCache.insert(links, page->id);
|
||||||
if (page->pendingTill > 0
|
if (page->pendingTill > 0
|
||||||
&& page->pendingTill <= base::unixtime::now()) {
|
&& page->pendingTill <= base::unixtime::now()) {
|
||||||
page->pendingTill = -1;
|
page->pendingTill = 0;
|
||||||
|
page->failed = true;
|
||||||
}
|
}
|
||||||
if (links == _previewLinks
|
if (links == _previewLinks && !_previewDraft.removed) {
|
||||||
&& _previewState == Data::PreviewState::Allowed) {
|
_previewData = (page->id && !page->failed)
|
||||||
_previewData = (page->id && page->pendingTill >= 0)
|
|
||||||
? page.get()
|
? page.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
|
@ -7510,8 +7523,7 @@ void HistoryWidget::gotPreview(
|
||||||
session().data().sendWebPageGamePollNotifications();
|
session().data().sendWebPageGamePollNotifications();
|
||||||
} else if (result.type() == mtpc_messageMediaEmpty) {
|
} else if (result.type() == mtpc_messageMediaEmpty) {
|
||||||
_previewCache.insert(links, 0);
|
_previewCache.insert(links, 0);
|
||||||
if (links == _previewLinks
|
if (links == _previewLinks && !_previewDraft.removed) {
|
||||||
&& _previewState == Data::PreviewState::Allowed) {
|
|
||||||
_previewData = nullptr;
|
_previewData = nullptr;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
@ -7520,7 +7532,7 @@ void HistoryWidget::gotPreview(
|
||||||
|
|
||||||
void HistoryWidget::updatePreview() {
|
void HistoryWidget::updatePreview() {
|
||||||
_previewTimer.cancel();
|
_previewTimer.cancel();
|
||||||
if (_previewData && _previewData->pendingTill >= 0) {
|
if (_previewData && !_previewData->failed) {
|
||||||
_fieldBarCancel->show();
|
_fieldBarCancel->show();
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
if (_previewData->pendingTill) {
|
if (_previewData->pendingTill) {
|
||||||
|
@ -7924,11 +7936,12 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
} else if (hasForward) {
|
} else if (hasForward) {
|
||||||
backy -= st::historyReplyHeight;
|
backy -= st::historyReplyHeight;
|
||||||
backh += st::historyReplyHeight;
|
backh += st::historyReplyHeight;
|
||||||
} else if (_previewData && _previewData->pendingTill >= 0) {
|
} else if (_previewData && !_previewData->failed) {
|
||||||
backy -= st::historyReplyHeight;
|
backy -= st::historyReplyHeight;
|
||||||
backh += st::historyReplyHeight;
|
backh += st::historyReplyHeight;
|
||||||
}
|
}
|
||||||
auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
|
auto drawWebPagePreview = (_previewData && !_previewData->failed)
|
||||||
|
&& !_replyForwardPressed;
|
||||||
p.setInactive(
|
p.setInactive(
|
||||||
controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any));
|
controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any));
|
||||||
p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg);
|
p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg);
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "chat_helpers/bot_command.h"
|
#include "chat_helpers/bot_command.h"
|
||||||
#include "chat_helpers/field_autocomplete.h"
|
#include "chat_helpers/field_autocomplete.h"
|
||||||
|
#include "data/data_drafts.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "ui/widgets/fields/input_field.h"
|
#include "ui/widgets/fields/input_field.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
|
@ -30,7 +31,6 @@ class Error;
|
||||||
} // namespace MTP
|
} // namespace MTP
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
enum class PreviewState : char;
|
|
||||||
class PhotoMedia;
|
class PhotoMedia;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
@ -682,7 +682,7 @@ private:
|
||||||
Ui::Text::String _previewTitle;
|
Ui::Text::String _previewTitle;
|
||||||
Ui::Text::String _previewDescription;
|
Ui::Text::String _previewDescription;
|
||||||
base::Timer _previewTimer;
|
base::Timer _previewTimer;
|
||||||
Data::PreviewState _previewState = Data::PreviewState();
|
Data::WebPageDraft _previewDraft;
|
||||||
|
|
||||||
bool _replyForwardPressed = false;
|
bool _replyForwardPressed = false;
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ using VoiceRecordBar = Controls::VoiceRecordBar;
|
||||||
using ForwardPanel = Controls::ForwardPanel;
|
using ForwardPanel = Controls::ForwardPanel;
|
||||||
|
|
||||||
[[nodiscard]] auto ShowWebPagePreview(WebPageData *page) {
|
[[nodiscard]] auto ShowWebPagePreview(WebPageData *page) {
|
||||||
return page && (page->pendingTill >= 0);
|
return page && !page->failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPageText ProcessWebPageData(WebPageData *page) {
|
WebPageText ProcessWebPageData(WebPageData *page) {
|
||||||
|
@ -128,9 +128,9 @@ public:
|
||||||
void cancel();
|
void cancel();
|
||||||
void checkPreview();
|
void checkPreview();
|
||||||
|
|
||||||
[[nodiscard]] Data::PreviewState state() const;
|
[[nodiscard]] Data::WebPageDraft draft() const;
|
||||||
void setState(Data::PreviewState value);
|
void setAllowed(bool allowed);
|
||||||
void refreshState(Data::PreviewState value, bool disable);
|
void refreshDraft(Data::WebPageDraft draft, bool disable);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> paintRequests() const;
|
[[nodiscard]] rpl::producer<> paintRequests() const;
|
||||||
[[nodiscard]] rpl::producer<QString> titleChanges() const;
|
[[nodiscard]] rpl::producer<QString> titleChanges() const;
|
||||||
|
@ -145,7 +145,7 @@ private:
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
MessageLinksParser _fieldLinksParser;
|
MessageLinksParser _fieldLinksParser;
|
||||||
|
|
||||||
Data::PreviewState _previewState = Data::PreviewState();
|
Data::WebPageDraft _previewDraft;
|
||||||
|
|
||||||
QStringList _parsedLinks;
|
QStringList _parsedLinks;
|
||||||
QString _previewLinks;
|
QString _previewLinks;
|
||||||
|
@ -172,7 +172,6 @@ WebpageProcessor::WebpageProcessor(
|
||||||
: _history(history)
|
: _history(history)
|
||||||
, _api(&history->session().mtp())
|
, _api(&history->session().mtp())
|
||||||
, _fieldLinksParser(field)
|
, _fieldLinksParser(field)
|
||||||
, _previewState(Data::PreviewState::Allowed)
|
|
||||||
, _timer([=] {
|
, _timer([=] {
|
||||||
if (!ShowWebPagePreview(_previewData)
|
if (!ShowWebPagePreview(_previewData)
|
||||||
|| _previewLinks.isEmpty()) {
|
|| _previewLinks.isEmpty()) {
|
||||||
|
@ -198,12 +197,7 @@ WebpageProcessor::WebpageProcessor(
|
||||||
|
|
||||||
_fieldLinksParser.list().changes(
|
_fieldLinksParser.list().changes(
|
||||||
) | rpl::start_with_next([=](QStringList &&parsed) {
|
) | rpl::start_with_next([=](QStringList &&parsed) {
|
||||||
if (_previewState == Data::PreviewState::EmptyOnEdit
|
|
||||||
&& _parsedLinks != parsed) {
|
|
||||||
_previewState = Data::PreviewState::Allowed;
|
|
||||||
}
|
|
||||||
_parsedLinks = std::move(parsed);
|
_parsedLinks = std::move(parsed);
|
||||||
|
|
||||||
checkPreview();
|
checkPreview();
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
@ -212,23 +206,23 @@ rpl::producer<> WebpageProcessor::paintRequests() const {
|
||||||
return _paintRequests.events();
|
return _paintRequests.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::PreviewState WebpageProcessor::state() const {
|
Data::WebPageDraft WebpageProcessor::draft() const {
|
||||||
return _previewState;
|
return _previewDraft;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebpageProcessor::setState(Data::PreviewState value) {
|
void WebpageProcessor::setAllowed(bool allowed) {
|
||||||
_previewState = value;
|
_previewDraft.removed = !allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebpageProcessor::refreshState(
|
void WebpageProcessor::refreshDraft(
|
||||||
Data::PreviewState value,
|
Data::WebPageDraft draft,
|
||||||
bool disable) {
|
bool disable) {
|
||||||
// Save links from _field to _parsedLinks without generating preview.
|
// Save links from _field to _parsedLinks without generating preview.
|
||||||
_previewState = Data::PreviewState::Cancelled;
|
_previewDraft = { .removed = true };
|
||||||
_fieldLinksParser.setDisabled(disable);
|
_fieldLinksParser.setDisabled(disable);
|
||||||
_fieldLinksParser.parseNow();
|
_fieldLinksParser.parseNow();
|
||||||
_parsedLinks = _fieldLinksParser.list().current();
|
_parsedLinks = _fieldLinksParser.list().current();
|
||||||
_previewState = value;
|
_previewDraft = draft;
|
||||||
checkPreview();
|
checkPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,21 +269,20 @@ void WebpageProcessor::getWebPagePreview() {
|
||||||
result.match([=](const MTPDmessageMediaWebPage &d) {
|
result.match([=](const MTPDmessageMediaWebPage &d) {
|
||||||
const auto page = _history->owner().processWebpage(d.vwebpage());
|
const auto page = _history->owner().processWebpage(d.vwebpage());
|
||||||
_previewCache.insert({ links, page->id });
|
_previewCache.insert({ links, page->id });
|
||||||
auto &till = page->pendingTill;
|
if (page->pendingTill > 0
|
||||||
if (till > 0 && till <= base::unixtime::now()) {
|
&& page->pendingTill <= base::unixtime::now()) {
|
||||||
till = -1;
|
page->pendingTill = 0;
|
||||||
|
page->failed = true;
|
||||||
}
|
}
|
||||||
if (links == _previewLinks
|
if (links == _previewLinks && !_previewDraft.removed) {
|
||||||
&& _previewState == Data::PreviewState::Allowed) {
|
_previewData = (page->id && !page->failed)
|
||||||
_previewData = (page->id && page->pendingTill >= 0)
|
|
||||||
? page.get()
|
? page.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
}, [=](const MTPDmessageMediaEmpty &d) {
|
}, [=](const MTPDmessageMediaEmpty &d) {
|
||||||
_previewCache.insert({ links, 0 });
|
_previewCache.insert({ links, 0 });
|
||||||
if (links == _previewLinks
|
if (links == _previewLinks && !_previewDraft.removed) {
|
||||||
&& _previewState == Data::PreviewState::Allowed) {
|
|
||||||
_previewData = nullptr;
|
_previewData = nullptr;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
@ -303,8 +296,7 @@ void WebpageProcessor::getWebPagePreview() {
|
||||||
void WebpageProcessor::checkPreview() {
|
void WebpageProcessor::checkPreview() {
|
||||||
const auto previewRestricted = _history->peer
|
const auto previewRestricted = _history->peer
|
||||||
&& _history->peer->amRestricted(ChatRestriction::EmbedLinks);
|
&& _history->peer->amRestricted(ChatRestriction::EmbedLinks);
|
||||||
if (_previewState != Data::PreviewState::Allowed
|
if (_previewDraft.removed || previewRestricted) {
|
||||||
|| previewRestricted) {
|
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1476,7 +1468,7 @@ void ComposeControls::setFieldText(
|
||||||
|
|
||||||
if (_preview) {
|
if (_preview) {
|
||||||
_preview->cancel();
|
_preview->cancel();
|
||||||
_preview->setState(Data::PreviewState::Allowed);
|
_preview->setAllowed(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1490,7 +1482,7 @@ void ComposeControls::saveFieldToHistoryLocalDraft() {
|
||||||
const auto key = draftKeyCurrent();
|
const auto key = draftKeyCurrent();
|
||||||
_history->setDraft(
|
_history->setDraft(
|
||||||
key,
|
key,
|
||||||
std::make_unique<Data::Draft>(_field, id, _preview->state()));
|
std::make_unique<Data::Draft>(_field, id, _preview->draft()));
|
||||||
} else {
|
} else {
|
||||||
_history->clearDraft(draftKeyCurrent());
|
_history->clearDraft(draftKeyCurrent());
|
||||||
}
|
}
|
||||||
|
@ -1625,7 +1617,7 @@ void ComposeControls::init() {
|
||||||
_header->previewCancelled(
|
_header->previewCancelled(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
if (_preview) {
|
if (_preview) {
|
||||||
_preview->setState(Data::PreviewState::Cancelled);
|
_preview->setAllowed(false);
|
||||||
}
|
}
|
||||||
_saveDraftText = true;
|
_saveDraftText = true;
|
||||||
_saveDraftStart = crl::now();
|
_saveDraftStart = crl::now();
|
||||||
|
@ -2009,7 +2001,7 @@ void ComposeControls::fieldChanged() {
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
_hasSendText = HasSendText(_field);
|
_hasSendText = HasSendText(_field);
|
||||||
if (!_hasSendText.current() && _preview) {
|
if (!_hasSendText.current() && _preview) {
|
||||||
_preview->setState(Data::PreviewState::Allowed);
|
_preview->setAllowed(true);
|
||||||
}
|
}
|
||||||
if (updateBotCommandShown() || updateLikeShown()) {
|
if (updateBotCommandShown() || updateLikeShown()) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -2113,7 +2105,7 @@ void ComposeControls::registerDraftSource() {
|
||||||
return Storage::MessageDraft{
|
return Storage::MessageDraft{
|
||||||
_header->getDraftReply(),
|
_header->getDraftReply(),
|
||||||
_field->getTextWithTags(),
|
_field->getTextWithTags(),
|
||||||
_preview->state(),
|
_preview->draft(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
auto draftSource = Storage::MessageDraftSource{
|
auto draftSource = Storage::MessageDraftSource{
|
||||||
|
@ -2179,7 +2171,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
}
|
}
|
||||||
_header->editMessage({});
|
_header->editMessage({});
|
||||||
_header->replyToMessage({});
|
_header->replyToMessage({});
|
||||||
_preview->refreshState(Data::PreviewState::Allowed, false);
|
_preview->refreshDraft({}, false);
|
||||||
_canReplaceMedia = false;
|
_canReplaceMedia = false;
|
||||||
_photoEditMedia = nullptr;
|
_photoEditMedia = nullptr;
|
||||||
return;
|
return;
|
||||||
|
@ -2194,7 +2186,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
||||||
if (_preview) {
|
if (_preview) {
|
||||||
const auto disablePreview = (editDraft != nullptr);
|
const auto disablePreview = (editDraft != nullptr);
|
||||||
_preview->refreshState(draft->previewState, disablePreview);
|
_preview->refreshDraft(draft->webpage, disablePreview);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draft == editDraft) {
|
if (draft == editDraft) {
|
||||||
|
@ -2215,7 +2207,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
item->fullId());
|
item->fullId());
|
||||||
}
|
}
|
||||||
_header->editMessage(editingId, _photoEditMedia != nullptr);
|
_header->editMessage(editingId, _photoEditMedia != nullptr);
|
||||||
_preview->refreshState(_preview->state(), disablePreview);
|
_preview->refreshDraft(_preview->draft(), disablePreview);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_canReplaceMedia = false;
|
_canReplaceMedia = false;
|
||||||
|
@ -2892,15 +2884,6 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
||||||
int(editData.text.size()),
|
int(editData.text.size()),
|
||||||
Ui::kQFixedMax
|
Ui::kQFixedMax
|
||||||
};
|
};
|
||||||
const auto previewPage = [&]() -> WebPageData* {
|
|
||||||
if (const auto media = item->media()) {
|
|
||||||
return media->webpage();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}();
|
|
||||||
const auto previewState = previewPage
|
|
||||||
? Data::PreviewState::Allowed
|
|
||||||
: Data::PreviewState::EmptyOnEdit;
|
|
||||||
const auto key = draftKey(DraftType::Edit);
|
const auto key = draftKey(DraftType::Edit);
|
||||||
_history->setDraft(
|
_history->setDraft(
|
||||||
key,
|
key,
|
||||||
|
@ -2911,7 +2894,7 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
||||||
.topicRootId = key.topicRootId(),
|
.topicRootId = key.topicRootId(),
|
||||||
},
|
},
|
||||||
cursor,
|
cursor,
|
||||||
previewState));
|
Data::WebPageDraft::FromItem(item)));
|
||||||
applyDraft();
|
applyDraft();
|
||||||
if (updateReplaceMediaButton()) {
|
if (updateReplaceMediaButton()) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -2997,7 +2980,7 @@ void ComposeControls::replyToMessage(FullReplyTo id) {
|
||||||
TextWithTags(),
|
TextWithTags(),
|
||||||
id,
|
id,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
Data::PreviewState::Allowed));
|
Data::WebPageDraft()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_header->replyToMessage(id);
|
_header->replyToMessage(id);
|
||||||
|
|
|
@ -43,7 +43,6 @@ namespace Data {
|
||||||
struct MessagePosition;
|
struct MessagePosition;
|
||||||
struct Draft;
|
struct Draft;
|
||||||
class DraftKey;
|
class DraftKey;
|
||||||
enum class PreviewState : char;
|
|
||||||
class PhotoMedia;
|
class PhotoMedia;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
|
|
@ -493,7 +493,7 @@ void ShowReplyToChatBox(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
reply,
|
reply,
|
||||||
cursor,
|
cursor,
|
||||||
Data::PreviewState::Allowed));
|
Data::WebPageDraft()));
|
||||||
history->clearLocalEditDraft(topicRootId);
|
history->clearLocalEditDraft(topicRootId);
|
||||||
history->session().changes().entryUpdated(
|
history->session().changes().entryUpdated(
|
||||||
thread,
|
thread,
|
||||||
|
|
|
@ -604,7 +604,7 @@ bool MainWidget::shareUrl(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
FullReplyTo{ .topicRootId = topicRootId },
|
FullReplyTo{ .topicRootId = topicRootId },
|
||||||
cursor,
|
cursor,
|
||||||
Data::PreviewState::Allowed));
|
Data::WebPageDraft()));
|
||||||
history->clearLocalEditDraft(topicRootId);
|
history->clearLocalEditDraft(topicRootId);
|
||||||
history->session().changes().entryUpdated(
|
history->session().changes().entryUpdated(
|
||||||
thread,
|
thread,
|
||||||
|
|
|
@ -575,7 +575,7 @@ chatInviteExported#ab4a819 flags:# revoked:flags.0?true permanent:flags.5?true r
|
||||||
chatInvitePublicJoinRequests#ed107ab7 = ExportedChatInvite;
|
chatInvitePublicJoinRequests#ed107ab7 = ExportedChatInvite;
|
||||||
|
|
||||||
chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
|
chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
|
||||||
chatInvite#3033e855 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true verified:flags.7?true scam:flags.8?true fake:flags.9?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector<User> color:flags.10?int = ChatInvite;
|
chatInvite#cde0ec40 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true verified:flags.7?true scam:flags.8?true fake:flags.9?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector<User> color:int = ChatInvite;
|
||||||
chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite;
|
chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite;
|
||||||
|
|
||||||
inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||||
|
@ -589,7 +589,7 @@ inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
|
||||||
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
|
||||||
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet;
|
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet;
|
||||||
|
|
||||||
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true text_color:flags.9?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
|
||||||
|
|
||||||
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
|
messages.stickerSet#6e153f16 set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = messages.StickerSet;
|
||||||
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
||||||
|
@ -705,7 +705,7 @@ botInlineMessageMediaGeo#51846fd flags:# geo:GeoPoint heading:flags.0?int period
|
||||||
botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||||
botInlineMessageMediaContact#18d1cdc2 flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
botInlineMessageMediaContact#18d1cdc2 flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||||
botInlineMessageMediaInvoice#354a9b09 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument currency:string total_amount:long reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
botInlineMessageMediaInvoice#354a9b09 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument currency:string total_amount:long reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||||
botInlineMessageMediaWebPage#809ad9a6 flags:# invert_media:flags.3?true force_large_media:flags.4?true force_small_media:flags.5?true manual:flags.7?true message:string entities:flags.1?Vector<MessageEntity> url:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
botInlineMessageMediaWebPage#809ad9a6 flags:# invert_media:flags.3?true force_large_media:flags.4?true force_small_media:flags.5?true manual:flags.7?true safe:flags.8?true message:string entities:flags.1?Vector<MessageEntity> url:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||||
|
|
||||||
botInlineResult#11965f3a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?WebDocument content:flags.5?WebDocument send_message:BotInlineMessage = BotInlineResult;
|
botInlineResult#11965f3a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?WebDocument content:flags.5?WebDocument send_message:BotInlineMessage = BotInlineResult;
|
||||||
botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
|
botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
|
||||||
|
@ -1586,7 +1586,7 @@ payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1
|
||||||
|
|
||||||
prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway;
|
prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway;
|
||||||
|
|
||||||
boost#53c300c8 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string = Boost;
|
boost#2a1c8c71 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string multiplier:flags.5?int = Boost;
|
||||||
|
|
||||||
premium.boostsList#86f8613c flags:# count:int boosts:Vector<Boost> next_offset:flags.0?string users:Vector<User> = premium.BoostsList;
|
premium.boostsList#86f8613c flags:# count:int boosts:Vector<Boost> next_offset:flags.0?string users:Vector<User> = premium.BoostsList;
|
||||||
|
|
||||||
|
@ -1594,7 +1594,7 @@ myBoost#c448415c flags:# slot:int peer:flags.0?Peer date:int expires:int cooldow
|
||||||
|
|
||||||
premium.myBoosts#9ae228e2 my_boosts:Vector<MyBoost> chats:Vector<Chat> users:Vector<User> = premium.MyBoosts;
|
premium.myBoosts#9ae228e2 my_boosts:Vector<MyBoost> chats:Vector<Chat> users:Vector<User> = premium.MyBoosts;
|
||||||
|
|
||||||
premium.boostsStatus#3d5daae6 flags:# my_boost:flags.2?true level:int current_level_boosts:int boosts:int gift_boosts:flags.3?int next_level_boosts:flags.0?int premium_audience:flags.1?StatsPercentValue boost_url:string prepaid_giveaways:flags.3?Vector<PrepaidGiveaway> my_boost_slots:flags.2?Vector<int> = premium.BoostsStatus;
|
premium.boostsStatus#4959427a flags:# my_boost:flags.2?true level:int current_level_boosts:int boosts:int gift_boosts:flags.4?int next_level_boosts:flags.0?int premium_audience:flags.1?StatsPercentValue boost_url:string prepaid_giveaways:flags.3?Vector<PrepaidGiveaway> my_boost_slots:flags.2?Vector<int> = premium.BoostsStatus;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
|
@ -2168,5 +2168,5 @@ stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool;
|
||||||
|
|
||||||
premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList;
|
premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList;
|
||||||
premium.getMyBoosts#be77b4a = premium.MyBoosts;
|
premium.getMyBoosts#be77b4a = premium.MyBoosts;
|
||||||
premium.applyBoost#184bc3b9 flags:# slots:flags.0?Vector<int> peer:InputPeer = Bool;
|
premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector<int> peer:InputPeer = premium.MyBoosts;
|
||||||
premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus;
|
premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus;
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ void EnumerateDrafts(
|
||||||
key,
|
key,
|
||||||
draft->reply,
|
draft->reply,
|
||||||
draft->textWithTags,
|
draft->textWithTags,
|
||||||
draft->previewState,
|
draft->webpage,
|
||||||
draft->cursor);
|
draft->cursor);
|
||||||
}
|
}
|
||||||
for (const auto &[key, source] : sources) {
|
for (const auto &[key, source] : sources) {
|
||||||
|
@ -1057,7 +1057,7 @@ void EnumerateDrafts(
|
||||||
key,
|
key,
|
||||||
draft.reply,
|
draft.reply,
|
||||||
draft.textWithTags,
|
draft.textWithTags,
|
||||||
draft.previewState,
|
draft.webpage,
|
||||||
cursor);
|
cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1122,13 +1122,18 @@ void Account::writeDrafts(not_null<History*> history) {
|
||||||
auto&&, // key
|
auto&&, // key
|
||||||
const FullReplyTo &reply,
|
const FullReplyTo &reply,
|
||||||
const TextWithTags &text,
|
const TextWithTags &text,
|
||||||
Data::PreviewState,
|
const Data::WebPageDraft &webpage,
|
||||||
auto&&) { // cursor
|
auto&&) { // cursor
|
||||||
size += sizeof(qint64) // key
|
size += sizeof(qint64) // key
|
||||||
+ Serialize::stringSize(text.text)
|
+ Serialize::stringSize(text.text)
|
||||||
+ TextUtilities::SerializeTagsSize(text.tags)
|
+ TextUtilities::SerializeTagsSize(text.tags)
|
||||||
+ sizeof(qint64) + sizeof(qint64) // messageId
|
+ sizeof(qint64) + sizeof(qint64) // messageId
|
||||||
+ sizeof(qint32); // previewState
|
+ Serialize::stringSize(webpage.url)
|
||||||
|
+ sizeof(qint32) // webpage.forceLargeMedia
|
||||||
|
+ sizeof(qint32) // webpage.forceSmallMedia
|
||||||
|
+ sizeof(qint32) // webpage.invert
|
||||||
|
+ sizeof(qint32) // webpage.manual
|
||||||
|
+ sizeof(qint32); // webpage.removed
|
||||||
};
|
};
|
||||||
EnumerateDrafts(
|
EnumerateDrafts(
|
||||||
map,
|
map,
|
||||||
|
@ -1146,7 +1151,7 @@ void Account::writeDrafts(not_null<History*> history) {
|
||||||
const Data::DraftKey &key,
|
const Data::DraftKey &key,
|
||||||
const FullReplyTo &reply,
|
const FullReplyTo &reply,
|
||||||
const TextWithTags &text,
|
const TextWithTags &text,
|
||||||
Data::PreviewState previewState,
|
const Data::WebPageDraft &webpage,
|
||||||
auto&&) { // cursor
|
auto&&) { // cursor
|
||||||
data.stream
|
data.stream
|
||||||
<< key.serialize()
|
<< key.serialize()
|
||||||
|
@ -1154,7 +1159,12 @@ void Account::writeDrafts(not_null<History*> history) {
|
||||||
<< TextUtilities::SerializeTags(text.tags)
|
<< TextUtilities::SerializeTags(text.tags)
|
||||||
<< qint64(reply.messageId.peer.value)
|
<< qint64(reply.messageId.peer.value)
|
||||||
<< qint64(reply.messageId.msg.bare)
|
<< qint64(reply.messageId.msg.bare)
|
||||||
<< qint32(previewState);
|
<< webpage.url
|
||||||
|
<< qint32(webpage.forceLargeMedia ? 1 : 0)
|
||||||
|
<< qint32(webpage.forceSmallMedia ? 1 : 0)
|
||||||
|
<< qint32(webpage.invert ? 1 : 0)
|
||||||
|
<< qint32(webpage.manual ? 1 : 0)
|
||||||
|
<< qint32(webpage.removed ? 1 : 0);
|
||||||
};
|
};
|
||||||
EnumerateDrafts(
|
EnumerateDrafts(
|
||||||
map,
|
map,
|
||||||
|
@ -1206,7 +1216,7 @@ void Account::writeDraftCursors(not_null<History*> history) {
|
||||||
const Data::DraftKey &key,
|
const Data::DraftKey &key,
|
||||||
auto&&, // reply
|
auto&&, // reply
|
||||||
auto&&, // text
|
auto&&, // text
|
||||||
Data::PreviewState,
|
auto&&, // webpage
|
||||||
const MessageCursor &cursor) { // cursor
|
const MessageCursor &cursor) { // cursor
|
||||||
data.stream
|
data.stream
|
||||||
<< key.serialize()
|
<< key.serialize()
|
||||||
|
@ -1370,18 +1380,33 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
||||||
QByteArray textTagsSerialized;
|
QByteArray textTagsSerialized;
|
||||||
qint64 keyValue = 0;
|
qint64 keyValue = 0;
|
||||||
qint64 messageIdPeer = 0, messageIdMsg = 0;
|
qint64 messageIdPeer = 0, messageIdMsg = 0;
|
||||||
qint32 keyValueOld = 0, uncheckedPreviewState = 0;
|
qint32 keyValueOld = 0;
|
||||||
|
QString webpageUrl;
|
||||||
|
qint32 webpageForceLargeMedia = 0;
|
||||||
|
qint32 webpageForceSmallMedia = 0;
|
||||||
|
qint32 webpageInvert = 0;
|
||||||
|
qint32 webpageManual = 0;
|
||||||
|
qint32 webpageRemoved = 0;
|
||||||
if (keysOld) {
|
if (keysOld) {
|
||||||
draft.stream >> keyValueOld;
|
draft.stream >> keyValueOld;
|
||||||
} else {
|
} else {
|
||||||
draft.stream >> keyValue;
|
draft.stream >> keyValue;
|
||||||
}
|
}
|
||||||
if (!rich) {
|
if (!rich) {
|
||||||
|
qint32 uncheckedPreviewState = 0;
|
||||||
draft.stream
|
draft.stream
|
||||||
>> text.text
|
>> text.text
|
||||||
>> textTagsSerialized
|
>> textTagsSerialized
|
||||||
>> messageIdMsg
|
>> messageIdMsg
|
||||||
>> uncheckedPreviewState;
|
>> uncheckedPreviewState;
|
||||||
|
enum class PreviewState : char {
|
||||||
|
Allowed,
|
||||||
|
Cancelled,
|
||||||
|
EmptyOnEdit,
|
||||||
|
};
|
||||||
|
if (uncheckedPreviewState == int(PreviewState::Cancelled)) {
|
||||||
|
webpageRemoved = 1;
|
||||||
|
}
|
||||||
messageIdPeer = peerId.value;
|
messageIdPeer = peerId.value;
|
||||||
} else {
|
} else {
|
||||||
draft.stream
|
draft.stream
|
||||||
|
@ -1389,17 +1414,16 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
||||||
>> textTagsSerialized
|
>> textTagsSerialized
|
||||||
>> messageIdPeer
|
>> messageIdPeer
|
||||||
>> messageIdMsg
|
>> messageIdMsg
|
||||||
>> uncheckedPreviewState;
|
>> webpageUrl
|
||||||
|
>> webpageForceLargeMedia
|
||||||
|
>> webpageForceSmallMedia
|
||||||
|
>> webpageInvert
|
||||||
|
>> webpageManual
|
||||||
|
>> webpageRemoved;
|
||||||
}
|
}
|
||||||
text.tags = TextUtilities::DeserializeTags(
|
text.tags = TextUtilities::DeserializeTags(
|
||||||
textTagsSerialized,
|
textTagsSerialized,
|
||||||
text.text.size());
|
text.text.size());
|
||||||
auto previewState = Data::PreviewState::Allowed;
|
|
||||||
switch (static_cast<Data::PreviewState>(uncheckedPreviewState)) {
|
|
||||||
case Data::PreviewState::Cancelled:
|
|
||||||
case Data::PreviewState::EmptyOnEdit:
|
|
||||||
previewState = Data::PreviewState(uncheckedPreviewState);
|
|
||||||
}
|
|
||||||
const auto key = keysOld
|
const auto key = keysOld
|
||||||
? Data::DraftKey::FromSerializedOld(keyValueOld)
|
? Data::DraftKey::FromSerializedOld(keyValueOld)
|
||||||
: Data::DraftKey::FromSerialized(keyValue);
|
: Data::DraftKey::FromSerialized(keyValue);
|
||||||
|
@ -1413,7 +1437,14 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
||||||
.topicRootId = key.topicRootId(),
|
.topicRootId = key.topicRootId(),
|
||||||
},
|
},
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
previewState));
|
Data::WebPageDraft{
|
||||||
|
.url = webpageUrl,
|
||||||
|
.forceLargeMedia = (webpageForceLargeMedia == 1),
|
||||||
|
.forceSmallMedia = (webpageForceSmallMedia == 1),
|
||||||
|
.invert = (webpageInvert == 1),
|
||||||
|
.manual = (webpageManual == 1),
|
||||||
|
.removed = (webpageRemoved == 1),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (draft.stream.status() != QDataStream::Ok) {
|
if (draft.stream.status() != QDataStream::Ok) {
|
||||||
|
@ -1478,9 +1509,9 @@ void Account::readDraftsWithCursorsLegacy(
|
||||||
msgData,
|
msgData,
|
||||||
FullReplyTo{ FullMsgId(peerId, MsgId(msgReplyTo)) },
|
FullReplyTo{ FullMsgId(peerId, MsgId(msgReplyTo)) },
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
(msgPreviewCancelled
|
Data::WebPageDraft{
|
||||||
? Data::PreviewState::Cancelled
|
.removed = (msgPreviewCancelled == 1),
|
||||||
: Data::PreviewState::Allowed)));
|
}));
|
||||||
}
|
}
|
||||||
if (editMsgId) {
|
if (editMsgId) {
|
||||||
map.emplace(
|
map.emplace(
|
||||||
|
@ -1489,9 +1520,9 @@ void Account::readDraftsWithCursorsLegacy(
|
||||||
editData,
|
editData,
|
||||||
FullReplyTo{ FullMsgId(peerId, editMsgId) },
|
FullReplyTo{ FullMsgId(peerId, editMsgId) },
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
(editPreviewCancelled
|
Data::WebPageDraft{
|
||||||
? Data::PreviewState::Cancelled
|
.removed = (editPreviewCancelled == 1),
|
||||||
: Data::PreviewState::Allowed)));
|
}));
|
||||||
}
|
}
|
||||||
readDraftCursors(peerId, map);
|
readDraftCursors(peerId, map);
|
||||||
history->setDraftsMap(std::move(map));
|
history->setDraftsMap(std::move(map));
|
||||||
|
|
|
@ -53,7 +53,7 @@ enum class StartResult : uchar;
|
||||||
struct MessageDraft {
|
struct MessageDraft {
|
||||||
FullReplyTo reply;
|
FullReplyTo reply;
|
||||||
TextWithTags textWithTags;
|
TextWithTags textWithTags;
|
||||||
Data::PreviewState previewState = Data::PreviewState::Allowed;
|
Data::WebPageDraft webpage;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MessageDraftSource {
|
struct MessageDraftSource {
|
||||||
|
|
|
@ -161,7 +161,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
|
||||||
+ normalizedName },
|
+ normalizedName },
|
||||||
FullReplyTo(),
|
FullReplyTo(),
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
Data::PreviewState::Allowed
|
Data::WebPageDraft()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1073,7 +1073,7 @@ void Manager::notificationActivated(
|
||||||
int(reply.text.size()),
|
int(reply.text.size()),
|
||||||
Ui::kQFixedMax,
|
Ui::kQFixedMax,
|
||||||
},
|
},
|
||||||
Data::PreviewState::Allowed);
|
Data::WebPageDraft());
|
||||||
history->setLocalDraft(std::move(draft));
|
history->setLocalDraft(std::move(draft));
|
||||||
}
|
}
|
||||||
window->widget()->showFromTray();
|
window->widget()->showFromTray();
|
||||||
|
|
|
@ -787,7 +787,7 @@ void SessionNavigation::applyBoostChecked(
|
||||||
MTP_flags(0),
|
MTP_flags(0),
|
||||||
MTPVector<MTPint>(), // slots
|
MTPVector<MTPint>(), // slots
|
||||||
channel->input
|
channel->input
|
||||||
)).done([=](const MTPBool &result) {
|
)).done([=](const MTPpremium_MyBoosts &result) {
|
||||||
done(true);
|
done(true);
|
||||||
}).fail([=](const MTP::Error &error) {
|
}).fail([=](const MTP::Error &error) {
|
||||||
showToast(u"Error: "_q + error.type());
|
showToast(u"Error: "_q + error.type());
|
||||||
|
@ -1556,7 +1556,7 @@ bool SessionController::switchInlineQuery(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
to.currentReplyTo,
|
to.currentReplyTo,
|
||||||
cursor,
|
cursor,
|
||||||
Data::PreviewState::Allowed);
|
Data::WebPageDraft());
|
||||||
|
|
||||||
auto params = Window::SectionShow();
|
auto params = Window::SectionShow();
|
||||||
params.reapplyLocalDraft = true;
|
params.reapplyLocalDraft = true;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user