mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Update API scheme, rich preview drafts.
This commit is contained in:
parent
b2e8e0431e
commit
b1823d981b
21 changed files with 268 additions and 174 deletions
Telegram/SourceFiles
apiwrap.cpp
data
data_drafts.cppdata_drafts.hdata_media_types.cppdata_media_types.hdata_session.cppdata_web_page.cppdata_web_page.h
history
mainwidget.cppmtproto/scheme
storage
support
window
|
@ -2135,8 +2135,10 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
|
||||
auto flags = MTPmessages_SaveDraft::Flags(0);
|
||||
auto &textWithTags = cloudDraft->textWithTags;
|
||||
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
|
||||
if (cloudDraft->webpage.removed) {
|
||||
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) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_reply_to;
|
||||
|
@ -2149,6 +2151,7 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
using PageFlag = MTPDinputMediaWebPage::Flag;
|
||||
history->startSavingCloudDraft(topicRootId);
|
||||
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
||||
MTP_flags(flags),
|
||||
|
@ -2156,7 +2159,15 @@ void ApiWrap::saveDraftsToCloud() {
|
|||
history->peer->input,
|
||||
MTP_string(textWithTags.text),
|
||||
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) {
|
||||
const auto requestId = response.requestId;
|
||||
history->finishSavingCloudDraft(
|
||||
|
@ -2243,7 +2254,7 @@ void ApiWrap::gotStickerSet(
|
|||
}
|
||||
|
||||
void ApiWrap::requestWebPageDelayed(not_null<WebPageData*> page) {
|
||||
if (page->pendingTill <= 0) {
|
||||
if (page->failed || !page->pendingTill) {
|
||||
return;
|
||||
}
|
||||
_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();) {
|
||||
if (i->second == req) {
|
||||
if (i->first->pendingTill > 0) {
|
||||
i->first->pendingTill = -1;
|
||||
i->first->pendingTill = 0;
|
||||
i->first->failed = 1;
|
||||
_session->data().notifyWebPageUpdateDelayed(i->first);
|
||||
}
|
||||
i = _webPagesPending.erase(i);
|
||||
|
|
|
@ -15,33 +15,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history_item_components.h"
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_web_page.h"
|
||||
#include "mainwidget.h"
|
||||
#include "storage/localstorage.h"
|
||||
|
||||
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(
|
||||
const TextWithTags &textWithTags,
|
||||
FullReplyTo reply,
|
||||
const MessageCursor &cursor,
|
||||
PreviewState previewState,
|
||||
WebPageDraft webpage,
|
||||
mtpRequestId saveRequestId)
|
||||
: textWithTags(textWithTags)
|
||||
, reply(std::move(reply))
|
||||
, cursor(cursor)
|
||||
, previewState(previewState)
|
||||
, webpage(webpage)
|
||||
, saveRequestId(saveRequestId) {
|
||||
}
|
||||
|
||||
Draft::Draft(
|
||||
not_null<const Ui::InputField*> field,
|
||||
FullReplyTo reply,
|
||||
PreviewState previewState,
|
||||
WebPageDraft webpage,
|
||||
mtpRequestId saveRequestId)
|
||||
: textWithTags(field->getTextWithTags())
|
||||
, reply(std::move(reply))
|
||||
, cursor(field)
|
||||
, previewState(previewState) {
|
||||
, webpage(webpage) {
|
||||
}
|
||||
|
||||
void ApplyPeerCloudDraft(
|
||||
|
@ -67,6 +87,23 @@ void ApplyPeerCloudDraft(
|
|||
const auto replyPeerId = reply.externalPeerId
|
||||
? reply.externalPeerId
|
||||
: 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>(
|
||||
textWithTags,
|
||||
FullReplyTo{
|
||||
|
@ -78,9 +115,7 @@ void ApplyPeerCloudDraft(
|
|||
.topicRootId = topicRootId,
|
||||
},
|
||||
MessageCursor(Ui::kQFixedMax, Ui::kQFixedMax, Ui::kQFixedMax),
|
||||
(draft.is_no_webpage()
|
||||
? Data::PreviewState::Cancelled
|
||||
: Data::PreviewState::Allowed));
|
||||
std::move(webpage));
|
||||
cloudDraft->date = date;
|
||||
|
||||
history->setCloudDraft(std::move(cloudDraft));
|
||||
|
|
|
@ -30,10 +30,19 @@ void ClearPeerCloudDraft(
|
|||
MsgId topicRootId,
|
||||
TimeId date);
|
||||
|
||||
enum class PreviewState : char {
|
||||
Allowed,
|
||||
Cancelled,
|
||||
EmptyOnEdit,
|
||||
struct WebPageDraft {
|
||||
[[nodiscard]] static WebPageDraft FromItem(not_null<HistoryItem*> item);
|
||||
|
||||
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 {
|
||||
|
@ -42,19 +51,19 @@ struct Draft {
|
|||
const TextWithTags &textWithTags,
|
||||
FullReplyTo reply,
|
||||
const MessageCursor &cursor,
|
||||
PreviewState previewState,
|
||||
WebPageDraft webpage,
|
||||
mtpRequestId saveRequestId = 0);
|
||||
Draft(
|
||||
not_null<const Ui::InputField*> field,
|
||||
FullReplyTo reply,
|
||||
PreviewState previewState,
|
||||
WebPageDraft webpage,
|
||||
mtpRequestId saveRequestId = 0);
|
||||
|
||||
TimeId date = 0;
|
||||
TextWithTags textWithTags;
|
||||
FullReplyTo reply; // reply.messageId.msg is editMsgId for edit draft.
|
||||
MessageCursor cursor;
|
||||
PreviewState previewState = PreviewState::Allowed;
|
||||
WebPageDraft webpage;
|
||||
mtpRequestId saveRequestId = 0;
|
||||
};
|
||||
|
||||
|
@ -180,7 +189,7 @@ using HistoryDrafts = base::flat_map<DraftKey, std::unique_ptr<Draft>>;
|
|||
}
|
||||
return (a->textWithTags == b->textWithTags)
|
||||
&& (a->reply == b->reply)
|
||||
&& (a->previewState == b->previewState);
|
||||
&& (a->webpage == b->webpage);
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
|
|
|
@ -404,6 +404,10 @@ WebPageData *Media::webpage() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
MediaWebPageFlags Media::webpageFlags() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
const SharedContact *Media::sharedContact() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1462,6 +1466,10 @@ WebPageData *MediaWebPage::webpage() const {
|
|||
return _page;
|
||||
}
|
||||
|
||||
MediaWebPageFlags MediaWebPage::webpageFlags() const {
|
||||
return _flags;
|
||||
}
|
||||
|
||||
bool MediaWebPage::hasReplyPreview() const {
|
||||
if (const auto document = MediaWebPage::document()) {
|
||||
return document->hasThumbnail()
|
||||
|
|
|
@ -122,6 +122,7 @@ public:
|
|||
virtual DocumentData *document() const;
|
||||
virtual PhotoData *photo() const;
|
||||
virtual WebPageData *webpage() const;
|
||||
virtual MediaWebPageFlags webpageFlags() const;
|
||||
virtual const SharedContact *sharedContact() const;
|
||||
virtual const Call *call() const;
|
||||
virtual GameData *game() const;
|
||||
|
@ -381,6 +382,7 @@ public:
|
|||
DocumentData *document() const override;
|
||||
PhotoData *photo() const override;
|
||||
WebPageData *webpage() const override;
|
||||
MediaWebPageFlags webpageFlags() const override;
|
||||
|
||||
bool hasReplyPreview() const override;
|
||||
Image *replyPreview() const override;
|
||||
|
|
|
@ -3261,7 +3261,8 @@ not_null<WebPageData*> Session::processWebpage(const MTPWebPage &data) {
|
|||
case mtpc_webPageEmpty: {
|
||||
const auto result = webpage(data.c_webPageEmpty().vid().v);
|
||||
if (result->pendingTill > 0) {
|
||||
result->pendingTill = -1; // failed
|
||||
result->pendingTill = 0;
|
||||
result->failed = 1;
|
||||
notifyWebPageUpdateDelayed(result);
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -227,7 +227,7 @@ bool WebPageData::applyChanges(
|
|||
const QString &newAuthor,
|
||||
int newPendingTill) {
|
||||
if (newPendingTill != 0
|
||||
&& (!url.isEmpty() || pendingTill < 0)
|
||||
&& (!url.isEmpty() || failed)
|
||||
&& (!pendingTill
|
||||
|| pendingTill == newPendingTill
|
||||
|| newPendingTill < -1)) {
|
||||
|
|
|
@ -100,8 +100,9 @@ struct WebPageData {
|
|||
DocumentData *document = nullptr;
|
||||
WebPageCollage collage;
|
||||
int duration = 0;
|
||||
int pendingTill = 0;
|
||||
int version = 0;
|
||||
TimeId pendingTill = 0;
|
||||
uint32 version : 31 = 0;
|
||||
uint32 failed : 1 = 0;
|
||||
|
||||
private:
|
||||
void replaceDocumentGoodThumbnail();
|
||||
|
|
|
@ -203,13 +203,13 @@ void History::createLocalDraftFromCloud(MsgId topicRootId) {
|
|||
draft->textWithTags,
|
||||
draft->reply,
|
||||
draft->cursor,
|
||||
draft->previewState));
|
||||
draft->webpage));
|
||||
existing = localDraft(topicRootId);
|
||||
} else if (existing != draft) {
|
||||
existing->textWithTags = draft->textWithTags;
|
||||
existing->reply = draft->reply;
|
||||
existing->cursor = draft->cursor;
|
||||
existing->previewState = draft->previewState;
|
||||
existing->webpage = draft->webpage;
|
||||
}
|
||||
existing->date = draft->date;
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ Data::Draft *History::createCloudDraft(
|
|||
TextWithTags(),
|
||||
FullReplyTo(),
|
||||
MessageCursor(),
|
||||
Data::PreviewState::Allowed));
|
||||
Data::WebPageDraft()));
|
||||
cloudDraft(topicRootId)->date = TimeId(0);
|
||||
} else {
|
||||
auto existing = cloudDraft(topicRootId);
|
||||
|
@ -286,13 +286,13 @@ Data::Draft *History::createCloudDraft(
|
|||
fromDraft->textWithTags,
|
||||
fromDraft->reply,
|
||||
fromDraft->cursor,
|
||||
fromDraft->previewState));
|
||||
fromDraft->webpage));
|
||||
existing = cloudDraft(topicRootId);
|
||||
} else if (existing != fromDraft) {
|
||||
existing->textWithTags = fromDraft->textWithTags;
|
||||
existing->reply = fromDraft->reply;
|
||||
existing->cursor = fromDraft->cursor;
|
||||
existing->previewState = fromDraft->previewState;
|
||||
existing->webpage = fromDraft->webpage;
|
||||
}
|
||||
existing->date = base::unixtime::now();
|
||||
existing->reply.topicRootId = topicRootId;
|
||||
|
|
|
@ -206,7 +206,6 @@ HistoryWidget::HistoryWidget(
|
|||
, _updateEditTimeLeftDisplay([=] { updateField(); })
|
||||
, _fieldBarCancel(this, st::historyReplyCancel)
|
||||
, _previewTimer([=] { requestPreview(); })
|
||||
, _previewState(Data::PreviewState::Allowed)
|
||||
, _topBar(this, controller)
|
||||
, _scroll(
|
||||
this,
|
||||
|
@ -443,10 +442,6 @@ HistoryWidget::HistoryWidget(
|
|||
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
|
||||
_fieldLinksParser->list().changes(
|
||||
) | rpl::start_with_next([=](QStringList &&parsed) {
|
||||
if (_previewState == Data::PreviewState::EmptyOnEdit
|
||||
&& _parsedLinks != parsed) {
|
||||
_previewState = Data::PreviewState::Allowed;
|
||||
}
|
||||
_parsedLinks = std::move(parsed);
|
||||
checkPreview();
|
||||
}, lifetime());
|
||||
|
@ -1604,7 +1599,7 @@ void HistoryWidget::fieldChanged() {
|
|||
|
||||
updateSendButtonType();
|
||||
if (!HasSendText(_field)) {
|
||||
_previewState = Data::PreviewState::Allowed;
|
||||
_previewDraft = {};
|
||||
_fieldIsEmpty = true;
|
||||
} else if (_fieldIsEmpty) {
|
||||
_fieldIsEmpty = false;
|
||||
|
@ -1668,14 +1663,14 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
|||
.messageId = FullMsgId(_history->peer->id, _editMsgId),
|
||||
.topicRootId = topicRootId,
|
||||
},
|
||||
_previewState,
|
||||
_previewDraft,
|
||||
_saveEditMsgRequestId));
|
||||
} else {
|
||||
if (_replyTo || !_field->empty()) {
|
||||
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
_field,
|
||||
_replyTo,
|
||||
_previewState));
|
||||
_previewDraft));
|
||||
} else {
|
||||
_history->clearLocalDraft(topicRootId);
|
||||
}
|
||||
|
@ -1783,7 +1778,7 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(
|
|||
textWithTags,
|
||||
FullReplyTo(),
|
||||
cursor,
|
||||
Data::PreviewState::Allowed));
|
||||
Data::WebPageDraft()));
|
||||
applyDraft();
|
||||
return true;
|
||||
}
|
||||
|
@ -1935,7 +1930,7 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
}
|
||||
|
||||
// Save links from _field to _parsedLinks without generating preview.
|
||||
_previewState = Data::PreviewState::Cancelled;
|
||||
_previewDraft = { .removed = true };
|
||||
if (_editMsgId) {
|
||||
_fieldLinksParser->setDisabled(!_replyEditMsg
|
||||
|| (_replyEditMsg->media()
|
||||
|
@ -1943,7 +1938,7 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
}
|
||||
_fieldLinksParser->parseNow();
|
||||
_parsedLinks = _fieldLinksParser->list().current();
|
||||
_previewState = draft->previewState;
|
||||
_previewDraft = draft->webpage;
|
||||
checkPreview();
|
||||
|
||||
return true;
|
||||
|
@ -2471,7 +2466,7 @@ void HistoryWidget::registerDraftSource() {
|
|||
? FullReplyTo{ FullMsgId(peerId, editMsgId) }
|
||||
: _replyTo),
|
||||
_field->getTextWithTags(),
|
||||
_previewState,
|
||||
_previewDraft,
|
||||
};
|
||||
};
|
||||
auto draftSource = Storage::MessageDraftSource{
|
||||
|
@ -2909,7 +2904,7 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
if (_editMsgId
|
||||
|| _replyTo
|
||||
|| readyToForward()
|
||||
|| (_previewData && _previewData->pendingTill >= 0)
|
||||
|| (_previewData && !_previewData->failed)
|
||||
|| _kbReplyTo) {
|
||||
if (_fieldBarCancel->isHidden()) {
|
||||
_fieldBarCancel->show();
|
||||
|
@ -3766,11 +3761,11 @@ void HistoryWidget::saveEditMsg() {
|
|||
cancelEdit();
|
||||
return;
|
||||
}
|
||||
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
|
||||
const auto webPageId = _previewDraft.removed
|
||||
? CancelledWebPageId
|
||||
: ((_previewData && _previewData->pendingTill >= 0)
|
||||
? _previewData->id
|
||||
: WebPageId(0));
|
||||
: (_previewData && !_previewData->failed)
|
||||
? _previewData->id
|
||||
: WebPageId();
|
||||
|
||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||
const auto prepareFlags = Ui::ItemTextOptions(
|
||||
|
@ -3925,11 +3920,11 @@ void HistoryWidget::send(Api::SendOptions options) {
|
|||
_cornerButtons.clearReplyReturns();
|
||||
}
|
||||
|
||||
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
|
||||
const auto webPageId = _previewDraft.removed
|
||||
? CancelledWebPageId
|
||||
: ((_previewData && _previewData->pendingTill >= 0)
|
||||
? _previewData->id
|
||||
: WebPageId(0));
|
||||
: (_previewData && !_previewData->failed)
|
||||
? _previewData->id
|
||||
: WebPageId();
|
||||
|
||||
auto message = Api::MessageToSend(prepareSendAction(options));
|
||||
message.textWithTags = _field->getTextWithAppliedMarkdown();
|
||||
|
@ -3950,7 +3945,9 @@ void HistoryWidget::send(Api::SendOptions options) {
|
|||
|
||||
hideSelectorControlsAnimated();
|
||||
|
||||
if (_previewData && _previewData->pendingTill) previewCancel();
|
||||
if (_previewData && _previewData->pendingTill) {
|
||||
previewCancel();
|
||||
}
|
||||
setInnerFocus();
|
||||
|
||||
if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) {
|
||||
|
@ -4790,7 +4787,10 @@ void HistoryWidget::toggleKeyboard(bool manual) {
|
|||
_field->setMaxHeight(computeMaxFieldHeight());
|
||||
|
||||
_kbReplyTo = nullptr;
|
||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_editMsgId && !_replyTo) {
|
||||
if (!readyToForward()
|
||||
&& (!_previewData || _previewData->failed)
|
||||
&& !_editMsgId
|
||||
&& !_replyTo) {
|
||||
_fieldBarCancel->hide();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
@ -5775,7 +5775,10 @@ void HistoryWidget::updateHistoryGeometry(
|
|||
} else if (writeRestriction().has_value()) {
|
||||
newScrollHeight -= _unblock->height();
|
||||
}
|
||||
if (_editMsgId || replyTo() || readyToForward() || (_previewData && _previewData->pendingTill >= 0)) {
|
||||
if (_editMsgId
|
||||
|| replyTo()
|
||||
|| readyToForward()
|
||||
|| (_previewData && !_previewData->failed)) {
|
||||
newScrollHeight -= st::historyReplyHeight;
|
||||
}
|
||||
if (_kbShown) {
|
||||
|
@ -6077,7 +6080,9 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
|||
_field->setMaxHeight(computeMaxFieldHeight());
|
||||
_kbShown = false;
|
||||
_kbReplyTo = nullptr;
|
||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyTo) {
|
||||
if (!readyToForward()
|
||||
&& (!_previewData || _previewData->failed)
|
||||
&& !_replyTo) {
|
||||
_fieldBarCancel->hide();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
@ -6093,7 +6098,10 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
|||
_field->setMaxHeight(computeMaxFieldHeight());
|
||||
_kbShown = false;
|
||||
_kbReplyTo = nullptr;
|
||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyTo && !_editMsgId) {
|
||||
if (!readyToForward()
|
||||
&& (!_previewData || _previewData->failed)
|
||||
&& !_replyTo
|
||||
&& !_editMsgId) {
|
||||
_fieldBarCancel->hide();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
@ -6138,7 +6146,7 @@ int HistoryWidget::computeMaxFieldHeight() const {
|
|||
- ((_editMsgId
|
||||
|| replyTo()
|
||||
|| readyToForward()
|
||||
|| (_previewData && _previewData->pendingTill >= 0))
|
||||
|| (_previewData && !_previewData->failed))
|
||||
? st::historyReplyHeight
|
||||
: 0)
|
||||
- (2 * st::historySendPadding)
|
||||
|
@ -6242,6 +6250,15 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
|||
_peer,
|
||||
Window::SectionShow::Way::Forward,
|
||||
_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;
|
||||
|
||||
previewCancel();
|
||||
_previewState = Data::PreviewState::Allowed;
|
||||
_previewDraft = {};
|
||||
}
|
||||
|
||||
void HistoryWidget::clearFieldText(
|
||||
|
@ -7171,7 +7188,7 @@ void HistoryWidget::setReplyFieldsFromProcessing() {
|
|||
TextWithTags(),
|
||||
id,
|
||||
MessageCursor(),
|
||||
Data::PreviewState::Allowed));
|
||||
Data::WebPageDraft()));
|
||||
}
|
||||
} else {
|
||||
_replyEditMsg = item;
|
||||
|
@ -7218,7 +7235,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
|||
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||
_field,
|
||||
_replyTo,
|
||||
_previewState));
|
||||
_previewDraft));
|
||||
} else {
|
||||
_history->clearLocalDraft({});
|
||||
}
|
||||
|
@ -7230,23 +7247,17 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
|||
int(editData.text.size()),
|
||||
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 previewDraft = Data::WebPageDraft::FromItem(item);
|
||||
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
||||
editData,
|
||||
FullReplyTo{ item->fullId() },
|
||||
cursor,
|
||||
previewState));
|
||||
previewDraft));
|
||||
applyDraft();
|
||||
|
||||
_previewData = previewPage;
|
||||
_previewData = previewDraft.id
|
||||
? session().data().webpage(previewDraft.id).get()
|
||||
: nullptr;
|
||||
if (_previewData) {
|
||||
updatePreview();
|
||||
}
|
||||
|
@ -7316,7 +7327,9 @@ bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
|||
_processingReplyItem = _replyEditMsg = nullptr;
|
||||
_processingReplyTo = _replyTo = FullReplyTo();
|
||||
mouseMoveEvent(0);
|
||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_kbReplyTo) {
|
||||
if (!readyToForward()
|
||||
&& (!_previewData || _previewData->failed)
|
||||
&& !_kbReplyTo) {
|
||||
_fieldBarCancel->hide();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
@ -7387,7 +7400,9 @@ void HistoryWidget::cancelEdit() {
|
|||
saveDraft();
|
||||
|
||||
mouseMoveEvent(nullptr);
|
||||
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !replyTo()) {
|
||||
if (!readyToForward()
|
||||
&& (!_previewData || _previewData->failed)
|
||||
&& !replyTo()) {
|
||||
_fieldBarCancel->hide();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
@ -7408,8 +7423,8 @@ void HistoryWidget::cancelEdit() {
|
|||
void HistoryWidget::cancelFieldAreaState() {
|
||||
controller()->hideLayer();
|
||||
_replyForwardPressed = false;
|
||||
if (_previewData && _previewData->pendingTill >= 0) {
|
||||
_previewState = Data::PreviewState::Cancelled;
|
||||
if (_previewData && !_previewData->failed) {
|
||||
_previewDraft = { .removed = true };
|
||||
previewCancel();
|
||||
|
||||
_saveDraftText = true;
|
||||
|
@ -7437,7 +7452,7 @@ void HistoryWidget::checkPreview() {
|
|||
const auto previewRestricted = [&] {
|
||||
return _peer && _peer->amRestricted(ChatRestriction::EmbedLinks);
|
||||
}();
|
||||
if (_previewState != Data::PreviewState::Allowed || previewRestricted) {
|
||||
if (_previewDraft.removed || previewRestricted) {
|
||||
previewCancel();
|
||||
return;
|
||||
}
|
||||
|
@ -7446,7 +7461,7 @@ void HistoryWidget::checkPreview() {
|
|||
_api.request(base::take(_previewRequest)).cancel();
|
||||
_previewLinks = links;
|
||||
if (_previewLinks.isEmpty()) {
|
||||
if (_previewData && _previewData->pendingTill >= 0) {
|
||||
if (_previewData && !_previewData->failed) {
|
||||
previewCancel();
|
||||
}
|
||||
} else {
|
||||
|
@ -7462,7 +7477,7 @@ void HistoryWidget::checkPreview() {
|
|||
} else if (i.value()) {
|
||||
_previewData = session().data().webpage(i.value());
|
||||
updatePreview();
|
||||
} else if (_previewData && _previewData->pendingTill >= 0) {
|
||||
} else if (_previewData && !_previewData->failed) {
|
||||
previewCancel();
|
||||
}
|
||||
}
|
||||
|
@ -7470,9 +7485,7 @@ void HistoryWidget::checkPreview() {
|
|||
}
|
||||
|
||||
void HistoryWidget::requestPreview() {
|
||||
if (!_previewData
|
||||
|| (_previewData->pendingTill <= 0)
|
||||
|| _previewLinks.isEmpty()) {
|
||||
if (!_previewData || _previewData->failed || _previewLinks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto links = _previewLinks;
|
||||
|
@ -7498,11 +7511,11 @@ void HistoryWidget::gotPreview(
|
|||
_previewCache.insert(links, page->id);
|
||||
if (page->pendingTill > 0
|
||||
&& page->pendingTill <= base::unixtime::now()) {
|
||||
page->pendingTill = -1;
|
||||
page->pendingTill = 0;
|
||||
page->failed = true;
|
||||
}
|
||||
if (links == _previewLinks
|
||||
&& _previewState == Data::PreviewState::Allowed) {
|
||||
_previewData = (page->id && page->pendingTill >= 0)
|
||||
if (links == _previewLinks && !_previewDraft.removed) {
|
||||
_previewData = (page->id && !page->failed)
|
||||
? page.get()
|
||||
: nullptr;
|
||||
updatePreview();
|
||||
|
@ -7510,8 +7523,7 @@ void HistoryWidget::gotPreview(
|
|||
session().data().sendWebPageGamePollNotifications();
|
||||
} else if (result.type() == mtpc_messageMediaEmpty) {
|
||||
_previewCache.insert(links, 0);
|
||||
if (links == _previewLinks
|
||||
&& _previewState == Data::PreviewState::Allowed) {
|
||||
if (links == _previewLinks && !_previewDraft.removed) {
|
||||
_previewData = nullptr;
|
||||
updatePreview();
|
||||
}
|
||||
|
@ -7520,7 +7532,7 @@ void HistoryWidget::gotPreview(
|
|||
|
||||
void HistoryWidget::updatePreview() {
|
||||
_previewTimer.cancel();
|
||||
if (_previewData && _previewData->pendingTill >= 0) {
|
||||
if (_previewData && !_previewData->failed) {
|
||||
_fieldBarCancel->show();
|
||||
updateMouseTracking();
|
||||
if (_previewData->pendingTill) {
|
||||
|
@ -7924,11 +7936,12 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
|||
} else if (hasForward) {
|
||||
backy -= st::historyReplyHeight;
|
||||
backh += st::historyReplyHeight;
|
||||
} else if (_previewData && _previewData->pendingTill >= 0) {
|
||||
} else if (_previewData && !_previewData->failed) {
|
||||
backy -= st::historyReplyHeight;
|
||||
backh += st::historyReplyHeight;
|
||||
}
|
||||
auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
|
||||
auto drawWebPagePreview = (_previewData && !_previewData->failed)
|
||||
&& !_replyForwardPressed;
|
||||
p.setInactive(
|
||||
controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any));
|
||||
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 "chat_helpers/bot_command.h"
|
||||
#include "chat_helpers/field_autocomplete.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "ui/widgets/fields/input_field.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
@ -30,7 +31,6 @@ class Error;
|
|||
} // namespace MTP
|
||||
|
||||
namespace Data {
|
||||
enum class PreviewState : char;
|
||||
class PhotoMedia;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -682,7 +682,7 @@ private:
|
|||
Ui::Text::String _previewTitle;
|
||||
Ui::Text::String _previewDescription;
|
||||
base::Timer _previewTimer;
|
||||
Data::PreviewState _previewState = Data::PreviewState();
|
||||
Data::WebPageDraft _previewDraft;
|
||||
|
||||
bool _replyForwardPressed = false;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ using VoiceRecordBar = Controls::VoiceRecordBar;
|
|||
using ForwardPanel = Controls::ForwardPanel;
|
||||
|
||||
[[nodiscard]] auto ShowWebPagePreview(WebPageData *page) {
|
||||
return page && (page->pendingTill >= 0);
|
||||
return page && !page->failed;
|
||||
}
|
||||
|
||||
WebPageText ProcessWebPageData(WebPageData *page) {
|
||||
|
@ -128,9 +128,9 @@ public:
|
|||
void cancel();
|
||||
void checkPreview();
|
||||
|
||||
[[nodiscard]] Data::PreviewState state() const;
|
||||
void setState(Data::PreviewState value);
|
||||
void refreshState(Data::PreviewState value, bool disable);
|
||||
[[nodiscard]] Data::WebPageDraft draft() const;
|
||||
void setAllowed(bool allowed);
|
||||
void refreshDraft(Data::WebPageDraft draft, bool disable);
|
||||
|
||||
[[nodiscard]] rpl::producer<> paintRequests() const;
|
||||
[[nodiscard]] rpl::producer<QString> titleChanges() const;
|
||||
|
@ -145,7 +145,7 @@ private:
|
|||
MTP::Sender _api;
|
||||
MessageLinksParser _fieldLinksParser;
|
||||
|
||||
Data::PreviewState _previewState = Data::PreviewState();
|
||||
Data::WebPageDraft _previewDraft;
|
||||
|
||||
QStringList _parsedLinks;
|
||||
QString _previewLinks;
|
||||
|
@ -172,7 +172,6 @@ WebpageProcessor::WebpageProcessor(
|
|||
: _history(history)
|
||||
, _api(&history->session().mtp())
|
||||
, _fieldLinksParser(field)
|
||||
, _previewState(Data::PreviewState::Allowed)
|
||||
, _timer([=] {
|
||||
if (!ShowWebPagePreview(_previewData)
|
||||
|| _previewLinks.isEmpty()) {
|
||||
|
@ -198,12 +197,7 @@ WebpageProcessor::WebpageProcessor(
|
|||
|
||||
_fieldLinksParser.list().changes(
|
||||
) | rpl::start_with_next([=](QStringList &&parsed) {
|
||||
if (_previewState == Data::PreviewState::EmptyOnEdit
|
||||
&& _parsedLinks != parsed) {
|
||||
_previewState = Data::PreviewState::Allowed;
|
||||
}
|
||||
_parsedLinks = std::move(parsed);
|
||||
|
||||
checkPreview();
|
||||
}, _lifetime);
|
||||
}
|
||||
|
@ -212,23 +206,23 @@ rpl::producer<> WebpageProcessor::paintRequests() const {
|
|||
return _paintRequests.events();
|
||||
}
|
||||
|
||||
Data::PreviewState WebpageProcessor::state() const {
|
||||
return _previewState;
|
||||
Data::WebPageDraft WebpageProcessor::draft() const {
|
||||
return _previewDraft;
|
||||
}
|
||||
|
||||
void WebpageProcessor::setState(Data::PreviewState value) {
|
||||
_previewState = value;
|
||||
void WebpageProcessor::setAllowed(bool allowed) {
|
||||
_previewDraft.removed = !allowed;
|
||||
}
|
||||
|
||||
void WebpageProcessor::refreshState(
|
||||
Data::PreviewState value,
|
||||
void WebpageProcessor::refreshDraft(
|
||||
Data::WebPageDraft draft,
|
||||
bool disable) {
|
||||
// Save links from _field to _parsedLinks without generating preview.
|
||||
_previewState = Data::PreviewState::Cancelled;
|
||||
_previewDraft = { .removed = true };
|
||||
_fieldLinksParser.setDisabled(disable);
|
||||
_fieldLinksParser.parseNow();
|
||||
_parsedLinks = _fieldLinksParser.list().current();
|
||||
_previewState = value;
|
||||
_previewDraft = draft;
|
||||
checkPreview();
|
||||
}
|
||||
|
||||
|
@ -275,21 +269,20 @@ void WebpageProcessor::getWebPagePreview() {
|
|||
result.match([=](const MTPDmessageMediaWebPage &d) {
|
||||
const auto page = _history->owner().processWebpage(d.vwebpage());
|
||||
_previewCache.insert({ links, page->id });
|
||||
auto &till = page->pendingTill;
|
||||
if (till > 0 && till <= base::unixtime::now()) {
|
||||
till = -1;
|
||||
if (page->pendingTill > 0
|
||||
&& page->pendingTill <= base::unixtime::now()) {
|
||||
page->pendingTill = 0;
|
||||
page->failed = true;
|
||||
}
|
||||
if (links == _previewLinks
|
||||
&& _previewState == Data::PreviewState::Allowed) {
|
||||
_previewData = (page->id && page->pendingTill >= 0)
|
||||
if (links == _previewLinks && !_previewDraft.removed) {
|
||||
_previewData = (page->id && !page->failed)
|
||||
? page.get()
|
||||
: nullptr;
|
||||
updatePreview();
|
||||
}
|
||||
}, [=](const MTPDmessageMediaEmpty &d) {
|
||||
_previewCache.insert({ links, 0 });
|
||||
if (links == _previewLinks
|
||||
&& _previewState == Data::PreviewState::Allowed) {
|
||||
if (links == _previewLinks && !_previewDraft.removed) {
|
||||
_previewData = nullptr;
|
||||
updatePreview();
|
||||
}
|
||||
|
@ -303,8 +296,7 @@ void WebpageProcessor::getWebPagePreview() {
|
|||
void WebpageProcessor::checkPreview() {
|
||||
const auto previewRestricted = _history->peer
|
||||
&& _history->peer->amRestricted(ChatRestriction::EmbedLinks);
|
||||
if (_previewState != Data::PreviewState::Allowed
|
||||
|| previewRestricted) {
|
||||
if (_previewDraft.removed || previewRestricted) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
@ -1476,7 +1468,7 @@ void ComposeControls::setFieldText(
|
|||
|
||||
if (_preview) {
|
||||
_preview->cancel();
|
||||
_preview->setState(Data::PreviewState::Allowed);
|
||||
_preview->setAllowed(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1490,7 +1482,7 @@ void ComposeControls::saveFieldToHistoryLocalDraft() {
|
|||
const auto key = draftKeyCurrent();
|
||||
_history->setDraft(
|
||||
key,
|
||||
std::make_unique<Data::Draft>(_field, id, _preview->state()));
|
||||
std::make_unique<Data::Draft>(_field, id, _preview->draft()));
|
||||
} else {
|
||||
_history->clearDraft(draftKeyCurrent());
|
||||
}
|
||||
|
@ -1625,7 +1617,7 @@ void ComposeControls::init() {
|
|||
_header->previewCancelled(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_preview) {
|
||||
_preview->setState(Data::PreviewState::Cancelled);
|
||||
_preview->setAllowed(false);
|
||||
}
|
||||
_saveDraftText = true;
|
||||
_saveDraftStart = crl::now();
|
||||
|
@ -2009,7 +2001,7 @@ void ComposeControls::fieldChanged() {
|
|||
updateSendButtonType();
|
||||
_hasSendText = HasSendText(_field);
|
||||
if (!_hasSendText.current() && _preview) {
|
||||
_preview->setState(Data::PreviewState::Allowed);
|
||||
_preview->setAllowed(true);
|
||||
}
|
||||
if (updateBotCommandShown() || updateLikeShown()) {
|
||||
updateControlsVisibility();
|
||||
|
@ -2113,7 +2105,7 @@ void ComposeControls::registerDraftSource() {
|
|||
return Storage::MessageDraft{
|
||||
_header->getDraftReply(),
|
||||
_field->getTextWithTags(),
|
||||
_preview->state(),
|
||||
_preview->draft(),
|
||||
};
|
||||
};
|
||||
auto draftSource = Storage::MessageDraftSource{
|
||||
|
@ -2179,7 +2171,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
}
|
||||
_header->editMessage({});
|
||||
_header->replyToMessage({});
|
||||
_preview->refreshState(Data::PreviewState::Allowed, false);
|
||||
_preview->refreshDraft({}, false);
|
||||
_canReplaceMedia = false;
|
||||
_photoEditMedia = nullptr;
|
||||
return;
|
||||
|
@ -2194,7 +2186,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
||||
if (_preview) {
|
||||
const auto disablePreview = (editDraft != nullptr);
|
||||
_preview->refreshState(draft->previewState, disablePreview);
|
||||
_preview->refreshDraft(draft->webpage, disablePreview);
|
||||
}
|
||||
|
||||
if (draft == editDraft) {
|
||||
|
@ -2215,7 +2207,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
|||
item->fullId());
|
||||
}
|
||||
_header->editMessage(editingId, _photoEditMedia != nullptr);
|
||||
_preview->refreshState(_preview->state(), disablePreview);
|
||||
_preview->refreshDraft(_preview->draft(), disablePreview);
|
||||
return true;
|
||||
}
|
||||
_canReplaceMedia = false;
|
||||
|
@ -2892,15 +2884,6 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
|||
int(editData.text.size()),
|
||||
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);
|
||||
_history->setDraft(
|
||||
key,
|
||||
|
@ -2911,7 +2894,7 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
|||
.topicRootId = key.topicRootId(),
|
||||
},
|
||||
cursor,
|
||||
previewState));
|
||||
Data::WebPageDraft::FromItem(item)));
|
||||
applyDraft();
|
||||
if (updateReplaceMediaButton()) {
|
||||
updateControlsVisibility();
|
||||
|
@ -2997,7 +2980,7 @@ void ComposeControls::replyToMessage(FullReplyTo id) {
|
|||
TextWithTags(),
|
||||
id,
|
||||
MessageCursor(),
|
||||
Data::PreviewState::Allowed));
|
||||
Data::WebPageDraft()));
|
||||
}
|
||||
} else {
|
||||
_header->replyToMessage(id);
|
||||
|
|
|
@ -43,7 +43,6 @@ namespace Data {
|
|||
struct MessagePosition;
|
||||
struct Draft;
|
||||
class DraftKey;
|
||||
enum class PreviewState : char;
|
||||
class PhotoMedia;
|
||||
} // namespace Data
|
||||
|
||||
|
|
|
@ -493,7 +493,7 @@ void ShowReplyToChatBox(
|
|||
textWithTags,
|
||||
reply,
|
||||
cursor,
|
||||
Data::PreviewState::Allowed));
|
||||
Data::WebPageDraft()));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->session().changes().entryUpdated(
|
||||
thread,
|
||||
|
|
|
@ -604,7 +604,7 @@ bool MainWidget::shareUrl(
|
|||
textWithTags,
|
||||
FullReplyTo{ .topicRootId = topicRootId },
|
||||
cursor,
|
||||
Data::PreviewState::Allowed));
|
||||
Data::WebPageDraft()));
|
||||
history->clearLocalEditDraft(topicRootId);
|
||||
history->session().changes().entryUpdated(
|
||||
thread,
|
||||
|
|
|
@ -575,7 +575,7 @@ chatInviteExported#ab4a819 flags:# revoked:flags.0?true permanent:flags.5?true r
|
|||
chatInvitePublicJoinRequests#ed107ab7 = ExportedChatInvite;
|
||||
|
||||
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;
|
||||
|
||||
inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
|
@ -589,7 +589,7 @@ inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
|
|||
inputStickerSetEmojiDefaultStatuses#29d0f5ee = 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.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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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.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---
|
||||
|
||||
|
@ -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.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;
|
||||
|
|
|
@ -1044,7 +1044,7 @@ void EnumerateDrafts(
|
|||
key,
|
||||
draft->reply,
|
||||
draft->textWithTags,
|
||||
draft->previewState,
|
||||
draft->webpage,
|
||||
draft->cursor);
|
||||
}
|
||||
for (const auto &[key, source] : sources) {
|
||||
|
@ -1057,7 +1057,7 @@ void EnumerateDrafts(
|
|||
key,
|
||||
draft.reply,
|
||||
draft.textWithTags,
|
||||
draft.previewState,
|
||||
draft.webpage,
|
||||
cursor);
|
||||
}
|
||||
}
|
||||
|
@ -1122,13 +1122,18 @@ void Account::writeDrafts(not_null<History*> history) {
|
|||
auto&&, // key
|
||||
const FullReplyTo &reply,
|
||||
const TextWithTags &text,
|
||||
Data::PreviewState,
|
||||
const Data::WebPageDraft &webpage,
|
||||
auto&&) { // cursor
|
||||
size += sizeof(qint64) // key
|
||||
+ Serialize::stringSize(text.text)
|
||||
+ TextUtilities::SerializeTagsSize(text.tags)
|
||||
+ 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(
|
||||
map,
|
||||
|
@ -1146,7 +1151,7 @@ void Account::writeDrafts(not_null<History*> history) {
|
|||
const Data::DraftKey &key,
|
||||
const FullReplyTo &reply,
|
||||
const TextWithTags &text,
|
||||
Data::PreviewState previewState,
|
||||
const Data::WebPageDraft &webpage,
|
||||
auto&&) { // cursor
|
||||
data.stream
|
||||
<< key.serialize()
|
||||
|
@ -1154,7 +1159,12 @@ void Account::writeDrafts(not_null<History*> history) {
|
|||
<< TextUtilities::SerializeTags(text.tags)
|
||||
<< qint64(reply.messageId.peer.value)
|
||||
<< 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(
|
||||
map,
|
||||
|
@ -1206,7 +1216,7 @@ void Account::writeDraftCursors(not_null<History*> history) {
|
|||
const Data::DraftKey &key,
|
||||
auto&&, // reply
|
||||
auto&&, // text
|
||||
Data::PreviewState,
|
||||
auto&&, // webpage
|
||||
const MessageCursor &cursor) { // cursor
|
||||
data.stream
|
||||
<< key.serialize()
|
||||
|
@ -1370,18 +1380,33 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
|||
QByteArray textTagsSerialized;
|
||||
qint64 keyValue = 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) {
|
||||
draft.stream >> keyValueOld;
|
||||
} else {
|
||||
draft.stream >> keyValue;
|
||||
}
|
||||
if (!rich) {
|
||||
qint32 uncheckedPreviewState = 0;
|
||||
draft.stream
|
||||
>> text.text
|
||||
>> textTagsSerialized
|
||||
>> messageIdMsg
|
||||
>> uncheckedPreviewState;
|
||||
enum class PreviewState : char {
|
||||
Allowed,
|
||||
Cancelled,
|
||||
EmptyOnEdit,
|
||||
};
|
||||
if (uncheckedPreviewState == int(PreviewState::Cancelled)) {
|
||||
webpageRemoved = 1;
|
||||
}
|
||||
messageIdPeer = peerId.value;
|
||||
} else {
|
||||
draft.stream
|
||||
|
@ -1389,17 +1414,16 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
|||
>> textTagsSerialized
|
||||
>> messageIdPeer
|
||||
>> messageIdMsg
|
||||
>> uncheckedPreviewState;
|
||||
>> webpageUrl
|
||||
>> webpageForceLargeMedia
|
||||
>> webpageForceSmallMedia
|
||||
>> webpageInvert
|
||||
>> webpageManual
|
||||
>> webpageRemoved;
|
||||
}
|
||||
text.tags = TextUtilities::DeserializeTags(
|
||||
textTagsSerialized,
|
||||
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
|
||||
? Data::DraftKey::FromSerializedOld(keyValueOld)
|
||||
: Data::DraftKey::FromSerialized(keyValue);
|
||||
|
@ -1413,7 +1437,14 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
|||
.topicRootId = key.topicRootId(),
|
||||
},
|
||||
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) {
|
||||
|
@ -1478,9 +1509,9 @@ void Account::readDraftsWithCursorsLegacy(
|
|||
msgData,
|
||||
FullReplyTo{ FullMsgId(peerId, MsgId(msgReplyTo)) },
|
||||
MessageCursor(),
|
||||
(msgPreviewCancelled
|
||||
? Data::PreviewState::Cancelled
|
||||
: Data::PreviewState::Allowed)));
|
||||
Data::WebPageDraft{
|
||||
.removed = (msgPreviewCancelled == 1),
|
||||
}));
|
||||
}
|
||||
if (editMsgId) {
|
||||
map.emplace(
|
||||
|
@ -1489,9 +1520,9 @@ void Account::readDraftsWithCursorsLegacy(
|
|||
editData,
|
||||
FullReplyTo{ FullMsgId(peerId, editMsgId) },
|
||||
MessageCursor(),
|
||||
(editPreviewCancelled
|
||||
? Data::PreviewState::Cancelled
|
||||
: Data::PreviewState::Allowed)));
|
||||
Data::WebPageDraft{
|
||||
.removed = (editPreviewCancelled == 1),
|
||||
}));
|
||||
}
|
||||
readDraftCursors(peerId, map);
|
||||
history->setDraftsMap(std::move(map));
|
||||
|
|
|
@ -53,7 +53,7 @@ enum class StartResult : uchar;
|
|||
struct MessageDraft {
|
||||
FullReplyTo reply;
|
||||
TextWithTags textWithTags;
|
||||
Data::PreviewState previewState = Data::PreviewState::Allowed;
|
||||
Data::WebPageDraft webpage;
|
||||
};
|
||||
|
||||
struct MessageDraftSource {
|
||||
|
|
|
@ -161,7 +161,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
|
|||
+ normalizedName },
|
||||
FullReplyTo(),
|
||||
MessageCursor(),
|
||||
Data::PreviewState::Allowed
|
||||
Data::WebPageDraft()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1073,7 +1073,7 @@ void Manager::notificationActivated(
|
|||
int(reply.text.size()),
|
||||
Ui::kQFixedMax,
|
||||
},
|
||||
Data::PreviewState::Allowed);
|
||||
Data::WebPageDraft());
|
||||
history->setLocalDraft(std::move(draft));
|
||||
}
|
||||
window->widget()->showFromTray();
|
||||
|
|
|
@ -787,7 +787,7 @@ void SessionNavigation::applyBoostChecked(
|
|||
MTP_flags(0),
|
||||
MTPVector<MTPint>(), // slots
|
||||
channel->input
|
||||
)).done([=](const MTPBool &result) {
|
||||
)).done([=](const MTPpremium_MyBoosts &result) {
|
||||
done(true);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
showToast(u"Error: "_q + error.type());
|
||||
|
@ -1556,7 +1556,7 @@ bool SessionController::switchInlineQuery(
|
|||
textWithTags,
|
||||
to.currentReplyTo,
|
||||
cursor,
|
||||
Data::PreviewState::Allowed);
|
||||
Data::WebPageDraft());
|
||||
|
||||
auto params = Window::SectionShow();
|
||||
params.reapplyLocalDraft = true;
|
||||
|
|
Loading…
Add table
Reference in a new issue