mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow sending custom webpage previews.
This commit is contained in:
parent
b1823d981b
commit
8b42161898
28 changed files with 396 additions and 173 deletions
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/data_drafts.h"
|
||||||
|
|
||||||
class History;
|
class History;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
@ -22,7 +24,6 @@ struct SendOptions {
|
||||||
TimeId scheduled = 0;
|
TimeId scheduled = 0;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
bool handleSupportSwitch = false;
|
bool handleSupportSwitch = false;
|
||||||
bool removeWebPageId = false;
|
|
||||||
bool hideViaBot = false;
|
bool hideViaBot = false;
|
||||||
};
|
};
|
||||||
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
|
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
|
||||||
|
@ -54,7 +55,7 @@ struct MessageToSend {
|
||||||
|
|
||||||
SendAction action;
|
SendAction action;
|
||||||
TextWithTags textWithTags;
|
TextWithTags textWithTags;
|
||||||
WebPageId webPageId = 0;
|
Data::WebPageDraft webPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RemoteFileInfo {
|
struct RemoteFileInfo {
|
||||||
|
|
|
@ -11,8 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_media.h"
|
#include "api/api_media.h"
|
||||||
#include "api/api_text_entities.h"
|
#include "api/api_text_entities.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "data/data_histories.h"
|
||||||
#include "data/data_scheduled_messages.h"
|
#include "data/data_scheduled_messages.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_web_page.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -45,6 +47,7 @@ template <typename DoneCallback, typename FailCallback>
|
||||||
mtpRequestId EditMessage(
|
mtpRequestId EditMessage(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const TextWithEntities &textWithEntities,
|
const TextWithEntities &textWithEntities,
|
||||||
|
Data::WebPageDraft webpage,
|
||||||
SendOptions options,
|
SendOptions options,
|
||||||
DoneCallback &&done,
|
DoneCallback &&done,
|
||||||
FailCallback &&fail,
|
FailCallback &&fail,
|
||||||
|
@ -71,9 +74,15 @@ mtpRequestId EditMessage(
|
||||||
| ((media && inputMedia.has_value())
|
| ((media && inputMedia.has_value())
|
||||||
? MTPmessages_EditMessage::Flag::f_media
|
? MTPmessages_EditMessage::Flag::f_media
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
| (options.removeWebPageId
|
| (webpage.removed
|
||||||
? MTPmessages_EditMessage::Flag::f_no_webpage
|
? MTPmessages_EditMessage::Flag::f_no_webpage
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
|
| ((!webpage.removed && !webpage.url.isEmpty())
|
||||||
|
? MTPmessages_EditMessage::Flag::f_media
|
||||||
|
: emptyFlag)
|
||||||
|
| ((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
||||||
|
? MTPmessages_EditMessage::Flag::f_invert_media
|
||||||
|
: emptyFlag)
|
||||||
| (!sentEntities.v.isEmpty()
|
| (!sentEntities.v.isEmpty()
|
||||||
? MTPmessages_EditMessage::Flag::f_entities
|
? MTPmessages_EditMessage::Flag::f_entities
|
||||||
: emptyFlag)
|
: emptyFlag)
|
||||||
|
@ -89,7 +98,7 @@ mtpRequestId EditMessage(
|
||||||
item->history()->peer->input,
|
item->history()->peer->input,
|
||||||
MTP_int(id),
|
MTP_int(id),
|
||||||
MTP_string(text),
|
MTP_string(text),
|
||||||
inputMedia.value_or(MTPInputMedia()),
|
inputMedia.value_or(Data::WebPageForMTP(webpage)),
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
sentEntities,
|
sentEntities,
|
||||||
MTP_int(options.scheduled)
|
MTP_int(options.scheduled)
|
||||||
|
@ -133,9 +142,15 @@ mtpRequestId EditMessage(
|
||||||
FailCallback &&fail,
|
FailCallback &&fail,
|
||||||
std::optional<MTPInputMedia> inputMedia = std::nullopt) {
|
std::optional<MTPInputMedia> inputMedia = std::nullopt) {
|
||||||
const auto &text = item->originalText();
|
const auto &text = item->originalText();
|
||||||
|
const auto webpage = (!item->media() || !item->media()->webpage())
|
||||||
|
? Data::WebPageDraft{ .removed = true }
|
||||||
|
: Data::WebPageDraft{
|
||||||
|
.id = item->media()->webpage()->id,
|
||||||
|
};
|
||||||
return EditMessage(
|
return EditMessage(
|
||||||
item,
|
item,
|
||||||
text,
|
text,
|
||||||
|
webpage,
|
||||||
options,
|
options,
|
||||||
std::forward<DoneCallback>(done),
|
std::forward<DoneCallback>(done),
|
||||||
std::forward<FailCallback>(fail),
|
std::forward<FailCallback>(fail),
|
||||||
|
@ -216,12 +231,19 @@ mtpRequestId EditCaption(
|
||||||
SendOptions options,
|
SendOptions options,
|
||||||
Fn<void()> done,
|
Fn<void()> done,
|
||||||
Fn<void(const QString &)> fail) {
|
Fn<void(const QString &)> fail) {
|
||||||
return EditMessage(item, caption, options, done, fail);
|
return EditMessage(
|
||||||
|
item,
|
||||||
|
caption,
|
||||||
|
Data::WebPageDraft(),
|
||||||
|
options,
|
||||||
|
done,
|
||||||
|
fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpRequestId EditTextMessage(
|
mtpRequestId EditTextMessage(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const TextWithEntities &caption,
|
const TextWithEntities &caption,
|
||||||
|
Data::WebPageDraft webpage,
|
||||||
SendOptions options,
|
SendOptions options,
|
||||||
Fn<void(mtpRequestId requestId)> done,
|
Fn<void(mtpRequestId requestId)> done,
|
||||||
Fn<void(const QString &, mtpRequestId requestId)> fail) {
|
Fn<void(const QString &, mtpRequestId requestId)> fail) {
|
||||||
|
@ -229,7 +251,7 @@ mtpRequestId EditTextMessage(
|
||||||
applyUpdates();
|
applyUpdates();
|
||||||
done(id);
|
done(id);
|
||||||
};
|
};
|
||||||
return EditMessage(item, caption, options, callback, fail);
|
return EditMessage(item, caption, webpage, options, callback, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
|
@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
struct WebPageDraft;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
class Error;
|
class Error;
|
||||||
} // namespace MTP
|
} // namespace MTP
|
||||||
|
@ -48,6 +52,7 @@ mtpRequestId EditCaption(
|
||||||
mtpRequestId EditTextMessage(
|
mtpRequestId EditTextMessage(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
const TextWithEntities &caption,
|
const TextWithEntities &caption,
|
||||||
|
Data::WebPageDraft webpage,
|
||||||
SendOptions options,
|
SendOptions options,
|
||||||
Fn<void(mtpRequestId requestId)> done,
|
Fn<void(mtpRequestId requestId)> done,
|
||||||
Fn<void(const QString &error, mtpRequestId requestId)> fail);
|
Fn<void(const QString &error, mtpRequestId requestId)> fail);
|
||||||
|
|
|
@ -2159,15 +2159,7 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
history->peer->input,
|
history->peer->input,
|
||||||
MTP_string(textWithTags.text),
|
MTP_string(textWithTags.text),
|
||||||
entities,
|
entities,
|
||||||
MTP_inputMediaWebPage(
|
Data::WebPageForMTP(cloudDraft->webpage)
|
||||||
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(
|
||||||
|
@ -3630,29 +3622,48 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
MTPstring msgText(MTP_string(sending.text));
|
MTPstring msgText(MTP_string(sending.text));
|
||||||
auto flags = NewMessageFlags(peer);
|
auto flags = NewMessageFlags(peer);
|
||||||
auto sendFlags = MTPmessages_SendMessage::Flags(0);
|
auto sendFlags = MTPmessages_SendMessage::Flags(0);
|
||||||
|
auto mediaFlags = MTPmessages_SendMedia::Flags(0);
|
||||||
if (action.replyTo) {
|
if (action.replyTo) {
|
||||||
flags |= MessageFlag::HasReplyInfo;
|
flags |= MessageFlag::HasReplyInfo;
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to;
|
||||||
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
|
||||||
}
|
}
|
||||||
const auto replyHeader = NewMessageReplyHeader(action);
|
const auto replyHeader = NewMessageReplyHeader(action);
|
||||||
MTPMessageMedia media = MTP_messageMediaEmpty();
|
MTPMessageMedia media = MTP_messageMediaEmpty();
|
||||||
if (message.webPageId == CancelledWebPageId) {
|
if (message.webPage.removed) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
|
||||||
} else if (message.webPageId) {
|
} else if (const auto fields = message.webPage; fields.id) {
|
||||||
auto page = _session->data().webpage(message.webPageId);
|
using PageFlag = MTPDmessageMediaWebPage::Flag;
|
||||||
|
using PendingFlag = MTPDwebPagePending::Flag;
|
||||||
|
const auto page = _session->data().webpage(fields.id);
|
||||||
media = MTP_messageMediaWebPage(
|
media = MTP_messageMediaWebPage(
|
||||||
MTP_flags(0),
|
MTP_flags(PageFlag()
|
||||||
|
| (fields.manual ? PageFlag::f_manual : PageFlag())
|
||||||
|
| (fields.forceLargeMedia
|
||||||
|
? PageFlag::f_force_large_media
|
||||||
|
: PageFlag())
|
||||||
|
| (fields.forceSmallMedia
|
||||||
|
? PageFlag::f_force_small_media
|
||||||
|
: PageFlag())),
|
||||||
MTP_webPagePending(
|
MTP_webPagePending(
|
||||||
MTP_flags(0),
|
MTP_flags(page->url.isEmpty()
|
||||||
|
? PendingFlag()
|
||||||
|
: PendingFlag::f_url),
|
||||||
MTP_long(page->id),
|
MTP_long(page->id),
|
||||||
MTPstring(), // url
|
MTP_string(page->url),
|
||||||
MTP_int(page->pendingTill)));
|
MTP_int(page->pendingTill)));
|
||||||
}
|
}
|
||||||
const auto anonymousPost = peer->amAnonymous();
|
const auto anonymousPost = peer->amAnonymous();
|
||||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||||
FillMessagePostFlags(action, peer, flags);
|
FillMessagePostFlags(action, peer, flags);
|
||||||
|
if (message.webPage.id && message.webPage.invert) {
|
||||||
|
flags |= MessageFlag::InvertMedia;
|
||||||
|
sendFlags |= MTPmessages_SendMessage::Flag::f_invert_media;
|
||||||
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
|
}
|
||||||
if (silentPost) {
|
if (silentPost) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
||||||
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||||
}
|
}
|
||||||
const auto sentEntities = Api::EntitiesToMTP(
|
const auto sentEntities = Api::EntitiesToMTP(
|
||||||
_session,
|
_session,
|
||||||
|
@ -3665,6 +3676,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
const auto topicRootId = action.replyTo.topicRootId;
|
const auto topicRootId = action.replyTo.topicRootId;
|
||||||
if (clearCloudDraft) {
|
if (clearCloudDraft) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
||||||
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
||||||
history->clearCloudDraft(topicRootId);
|
history->clearCloudDraft(topicRootId);
|
||||||
history->startSavingCloudDraft(topicRootId);
|
history->startSavingCloudDraft(topicRootId);
|
||||||
}
|
}
|
||||||
|
@ -3676,6 +3688,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
: _session->userPeerId();
|
: _session->userPeerId();
|
||||||
if (sendAs) {
|
if (sendAs) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
|
||||||
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_send_as;
|
||||||
}
|
}
|
||||||
const auto messagePostAuthor = peer->isBroadcast()
|
const auto messagePostAuthor = peer->isBroadcast()
|
||||||
? _session->user()->name()
|
? _session->user()->name()
|
||||||
|
@ -3683,6 +3696,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
if (action.options.scheduled) {
|
if (action.options.scheduled) {
|
||||||
flags |= MessageFlag::IsOrWasScheduled;
|
flags |= MessageFlag::IsOrWasScheduled;
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date;
|
||||||
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
||||||
}
|
}
|
||||||
const auto viaBotId = UserId();
|
const auto viaBotId = UserId();
|
||||||
lastMessage = history->addNewLocalMessage(
|
lastMessage = history->addNewLocalMessage(
|
||||||
|
@ -3696,27 +3710,18 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
sending,
|
sending,
|
||||||
media,
|
media,
|
||||||
HistoryMessageMarkupData());
|
HistoryMessageMarkupData());
|
||||||
histories.sendPreparedMessage(
|
const auto done = [=](
|
||||||
history,
|
const MTPUpdates &result,
|
||||||
action.replyTo,
|
const MTP::Response &response) {
|
||||||
randomId,
|
|
||||||
Data::Histories::PrepareMessage<MTPmessages_SendMessage>(
|
|
||||||
MTP_flags(sendFlags),
|
|
||||||
peer->input,
|
|
||||||
Data::Histories::ReplyToPlaceholder(),
|
|
||||||
msgText,
|
|
||||||
MTP_long(randomId),
|
|
||||||
MTPReplyMarkup(),
|
|
||||||
sentEntities,
|
|
||||||
MTP_int(action.options.scheduled),
|
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
|
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
|
||||||
if (clearCloudDraft) {
|
if (clearCloudDraft) {
|
||||||
history->finishSavingCloudDraft(
|
history->finishSavingCloudDraft(
|
||||||
topicRootId,
|
topicRootId,
|
||||||
UnixtimeFromMsgId(response.outerMsgId));
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
}
|
}
|
||||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
};
|
||||||
|
const auto fail = [=](
|
||||||
|
const MTP::Error &error,
|
||||||
|
const MTP::Response &response) {
|
||||||
if (error.type() == u"MESSAGE_EMPTY"_q) {
|
if (error.type() == u"MESSAGE_EMPTY"_q) {
|
||||||
lastMessage->destroy();
|
lastMessage->destroy();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3727,7 +3732,44 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
topicRootId,
|
topicRootId,
|
||||||
UnixtimeFromMsgId(response.outerMsgId));
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
if (!message.webPage.removed
|
||||||
|
&& (message.webPage.manual || sending.empty())
|
||||||
|
&& !message.webPage.url.isEmpty()) {
|
||||||
|
using PageFlag = MTPDinputMediaWebPage::Flag;
|
||||||
|
histories.sendPreparedMessage(
|
||||||
|
history,
|
||||||
|
action.replyTo,
|
||||||
|
randomId,
|
||||||
|
Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
|
||||||
|
MTP_flags(mediaFlags),
|
||||||
|
peer->input,
|
||||||
|
Data::Histories::ReplyToPlaceholder(),
|
||||||
|
Data::WebPageForMTP(message.webPage),
|
||||||
|
msgText,
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPReplyMarkup(),
|
||||||
|
sentEntities,
|
||||||
|
MTP_int(message.action.options.scheduled),
|
||||||
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
|
||||||
|
), done, fail);
|
||||||
|
} else {
|
||||||
|
histories.sendPreparedMessage(
|
||||||
|
history,
|
||||||
|
action.replyTo,
|
||||||
|
randomId,
|
||||||
|
Data::Histories::PrepareMessage<MTPmessages_SendMessage>(
|
||||||
|
MTP_flags(sendFlags),
|
||||||
|
peer->input,
|
||||||
|
Data::Histories::ReplyToPlaceholder(),
|
||||||
|
msgText,
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPReplyMarkup(),
|
||||||
|
sentEntities,
|
||||||
|
MTP_int(action.options.scheduled),
|
||||||
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
|
||||||
|
), done, fail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finishForwarding(action);
|
finishForwarding(action);
|
||||||
|
|
|
@ -74,6 +74,15 @@ MTPInputReplyTo ReplyToForMTP(
|
||||||
return MTPInputReplyTo();
|
return MTPInputReplyTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTPInputMedia WebPageForMTP(const Data::WebPageDraft &draft) {
|
||||||
|
using Flag = MTPDinputMediaWebPage::Flag;
|
||||||
|
return MTP_inputMediaWebPage(
|
||||||
|
MTP_flags(Flag::f_optional
|
||||||
|
| (draft.forceLargeMedia ? Flag::f_force_large_media : Flag())
|
||||||
|
| (draft.forceSmallMedia ? Flag::f_force_small_media : Flag())),
|
||||||
|
MTP_string(draft.url));
|
||||||
|
}
|
||||||
|
|
||||||
Histories::Histories(not_null<Session*> owner)
|
Histories::Histories(not_null<Session*> owner)
|
||||||
: _owner(owner)
|
: _owner(owner)
|
||||||
, _readRequestsTimer([=] { sendReadRequests(); }) {
|
, _readRequestsTimer([=] { sendReadRequests(); }) {
|
||||||
|
|
|
@ -25,10 +25,12 @@ namespace Data {
|
||||||
|
|
||||||
class Session;
|
class Session;
|
||||||
class Folder;
|
class Folder;
|
||||||
|
struct WebPageDraft;
|
||||||
|
|
||||||
[[nodiscard]] MTPInputReplyTo ReplyToForMTP(
|
[[nodiscard]] MTPInputReplyTo ReplyToForMTP(
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
FullReplyTo replyTo);
|
FullReplyTo replyTo);
|
||||||
|
[[nodiscard]] MTPInputMedia WebPageForMTP(const Data::WebPageDraft &draft);
|
||||||
|
|
||||||
class Histories final {
|
class Histories final {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1500,10 +1500,13 @@ bool MediaWebPage::replyPreviewLoaded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemPreview MediaWebPage::toPreview(ToPreviewOptions options) const {
|
ItemPreview MediaWebPage::toPreview(ToPreviewOptions options) const {
|
||||||
return { .text = options.translated
|
auto text = options.translated
|
||||||
? parent()->translatedText()
|
? parent()->translatedText()
|
||||||
: parent()->originalText()
|
: parent()->originalText();
|
||||||
};
|
if (text.empty()) {
|
||||||
|
text = Ui::Text::Colorized(_page->url);
|
||||||
|
}
|
||||||
|
return { .text = text };
|
||||||
}
|
}
|
||||||
|
|
||||||
TextWithEntities MediaWebPage::notificationText() const {
|
TextWithEntities MediaWebPage::notificationText() const {
|
||||||
|
|
|
@ -3260,6 +3260,7 @@ not_null<WebPageData*> Session::processWebpage(const MTPWebPage &data) {
|
||||||
return processWebpage(data.c_webPage());
|
return processWebpage(data.c_webPage());
|
||||||
case mtpc_webPageEmpty: {
|
case mtpc_webPageEmpty: {
|
||||||
const auto result = webpage(data.c_webPageEmpty().vid().v);
|
const auto result = webpage(data.c_webPageEmpty().vid().v);
|
||||||
|
result->type = WebPageType::None;
|
||||||
if (result->pendingTill > 0) {
|
if (result->pendingTill > 0) {
|
||||||
result->pendingTill = 0;
|
result->pendingTill = 0;
|
||||||
result->failed = 1;
|
result->failed = 1;
|
||||||
|
@ -3283,13 +3284,13 @@ not_null<WebPageData*> Session::processWebpage(const MTPDwebPage &data) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<WebPageData*> Session::processWebpage(const MTPDwebPagePending &data) {
|
not_null<WebPageData*> Session::processWebpage(
|
||||||
|
const MTPDwebPagePending &data) {
|
||||||
constexpr auto kDefaultPendingTimeout = 60;
|
constexpr auto kDefaultPendingTimeout = 60;
|
||||||
const auto result = webpage(data.vid().v);
|
const auto result = webpage(data.vid().v);
|
||||||
webpageApplyFields(
|
webpageApplyFields(
|
||||||
result,
|
result,
|
||||||
WebPageType::Article,
|
WebPageType::None,
|
||||||
false,
|
|
||||||
QString(),
|
QString(),
|
||||||
QString(),
|
QString(),
|
||||||
QString(),
|
QString(),
|
||||||
|
@ -3301,6 +3302,7 @@ not_null<WebPageData*> Session::processWebpage(const MTPDwebPagePending &data) {
|
||||||
WebPageCollage(),
|
WebPageCollage(),
|
||||||
0,
|
0,
|
||||||
QString(),
|
QString(),
|
||||||
|
false,
|
||||||
data.vdate().v
|
data.vdate().v
|
||||||
? data.vdate().v
|
? data.vdate().v
|
||||||
: (base::unixtime::now() + kDefaultPendingTimeout));
|
: (base::unixtime::now() + kDefaultPendingTimeout));
|
||||||
|
@ -3314,7 +3316,6 @@ not_null<WebPageData*> Session::webpage(
|
||||||
return webpage(
|
return webpage(
|
||||||
id,
|
id,
|
||||||
WebPageType::Article,
|
WebPageType::Article,
|
||||||
false,
|
|
||||||
QString(),
|
QString(),
|
||||||
QString(),
|
QString(),
|
||||||
siteName,
|
siteName,
|
||||||
|
@ -3325,13 +3326,13 @@ not_null<WebPageData*> Session::webpage(
|
||||||
WebPageCollage(),
|
WebPageCollage(),
|
||||||
0,
|
0,
|
||||||
QString(),
|
QString(),
|
||||||
|
false,
|
||||||
TimeId(0));
|
TimeId(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<WebPageData*> Session::webpage(
|
not_null<WebPageData*> Session::webpage(
|
||||||
WebPageId id,
|
WebPageId id,
|
||||||
WebPageType type,
|
WebPageType type,
|
||||||
bool hasLargeMedia,
|
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &displayUrl,
|
const QString &displayUrl,
|
||||||
const QString &siteName,
|
const QString &siteName,
|
||||||
|
@ -3342,12 +3343,12 @@ not_null<WebPageData*> Session::webpage(
|
||||||
WebPageCollage &&collage,
|
WebPageCollage &&collage,
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
|
bool hasLargeMedia,
|
||||||
TimeId pendingTill) {
|
TimeId pendingTill) {
|
||||||
const auto result = webpage(id);
|
const auto result = webpage(id);
|
||||||
webpageApplyFields(
|
webpageApplyFields(
|
||||||
result,
|
result,
|
||||||
type,
|
type,
|
||||||
hasLargeMedia,
|
|
||||||
url,
|
url,
|
||||||
displayUrl,
|
displayUrl,
|
||||||
siteName,
|
siteName,
|
||||||
|
@ -3359,6 +3360,7 @@ not_null<WebPageData*> Session::webpage(
|
||||||
std::move(collage),
|
std::move(collage),
|
||||||
duration,
|
duration,
|
||||||
author,
|
author,
|
||||||
|
hasLargeMedia,
|
||||||
pendingTill);
|
pendingTill);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3439,7 +3441,6 @@ void Session::webpageApplyFields(
|
||||||
webpageApplyFields(
|
webpageApplyFields(
|
||||||
page,
|
page,
|
||||||
(story ? WebPageType::Story : ParseWebPageType(data)),
|
(story ? WebPageType::Story : ParseWebPageType(data)),
|
||||||
data.is_has_large_media(),
|
|
||||||
qs(data.vurl()),
|
qs(data.vurl()),
|
||||||
qs(data.vdisplay_url()),
|
qs(data.vdisplay_url()),
|
||||||
siteName,
|
siteName,
|
||||||
|
@ -3459,13 +3460,13 @@ void Session::webpageApplyFields(
|
||||||
WebPageCollage(this, data),
|
WebPageCollage(this, data),
|
||||||
data.vduration().value_or_empty(),
|
data.vduration().value_or_empty(),
|
||||||
qs(data.vauthor().value_or_empty()),
|
qs(data.vauthor().value_or_empty()),
|
||||||
|
data.is_has_large_media(),
|
||||||
pendingTill);
|
pendingTill);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::webpageApplyFields(
|
void Session::webpageApplyFields(
|
||||||
not_null<WebPageData*> page,
|
not_null<WebPageData*> page,
|
||||||
WebPageType type,
|
WebPageType type,
|
||||||
bool hasLargeMedia,
|
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &displayUrl,
|
const QString &displayUrl,
|
||||||
const QString &siteName,
|
const QString &siteName,
|
||||||
|
@ -3477,11 +3478,11 @@ void Session::webpageApplyFields(
|
||||||
WebPageCollage &&collage,
|
WebPageCollage &&collage,
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
|
bool hasLargeMedia,
|
||||||
TimeId pendingTill) {
|
TimeId pendingTill) {
|
||||||
const auto requestPending = (!page->pendingTill && pendingTill > 0);
|
const auto requestPending = (!page->pendingTill && pendingTill > 0);
|
||||||
const auto changed = page->applyChanges(
|
const auto changed = page->applyChanges(
|
||||||
type,
|
type,
|
||||||
hasLargeMedia,
|
|
||||||
url,
|
url,
|
||||||
displayUrl,
|
displayUrl,
|
||||||
siteName,
|
siteName,
|
||||||
|
@ -3493,6 +3494,7 @@ void Session::webpageApplyFields(
|
||||||
std::move(collage),
|
std::move(collage),
|
||||||
duration,
|
duration,
|
||||||
author,
|
author,
|
||||||
|
hasLargeMedia,
|
||||||
pendingTill);
|
pendingTill);
|
||||||
if (requestPending) {
|
if (requestPending) {
|
||||||
_session->api().requestWebPageDelayed(page);
|
_session->api().requestWebPageDelayed(page);
|
||||||
|
|
|
@ -552,7 +552,6 @@ public:
|
||||||
[[nodiscard]] not_null<WebPageData*> webpage(
|
[[nodiscard]] not_null<WebPageData*> webpage(
|
||||||
WebPageId id,
|
WebPageId id,
|
||||||
WebPageType type,
|
WebPageType type,
|
||||||
bool hasLargeMedia,
|
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &displayUrl,
|
const QString &displayUrl,
|
||||||
const QString &siteName,
|
const QString &siteName,
|
||||||
|
@ -563,6 +562,7 @@ public:
|
||||||
WebPageCollage &&collage,
|
WebPageCollage &&collage,
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
|
bool hasLargeMedia,
|
||||||
TimeId pendingTill);
|
TimeId pendingTill);
|
||||||
|
|
||||||
[[nodiscard]] not_null<GameData*> game(GameId id);
|
[[nodiscard]] not_null<GameData*> game(GameId id);
|
||||||
|
@ -814,7 +814,6 @@ private:
|
||||||
void webpageApplyFields(
|
void webpageApplyFields(
|
||||||
not_null<WebPageData*> page,
|
not_null<WebPageData*> page,
|
||||||
WebPageType type,
|
WebPageType type,
|
||||||
bool hasLargeMedia,
|
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &displayUrl,
|
const QString &displayUrl,
|
||||||
const QString &siteName,
|
const QString &siteName,
|
||||||
|
@ -826,6 +825,7 @@ private:
|
||||||
WebPageCollage &&collage,
|
WebPageCollage &&collage,
|
||||||
int duration,
|
int duration,
|
||||||
const QString &author,
|
const QString &author,
|
||||||
|
bool hasLargeMedia,
|
||||||
TimeId pendingTill);
|
TimeId pendingTill);
|
||||||
|
|
||||||
void gameApplyFields(
|
void gameApplyFields(
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/text_entity.h"
|
#include "ui/text/text_entity.h"
|
||||||
|
|
||||||
|
@ -213,7 +214,6 @@ Main::Session &WebPageData::session() const {
|
||||||
|
|
||||||
bool WebPageData::applyChanges(
|
bool WebPageData::applyChanges(
|
||||||
WebPageType newType,
|
WebPageType newType,
|
||||||
bool newHasLargeMedia,
|
|
||||||
const QString &newUrl,
|
const QString &newUrl,
|
||||||
const QString &newDisplayUrl,
|
const QString &newDisplayUrl,
|
||||||
const QString &newSiteName,
|
const QString &newSiteName,
|
||||||
|
@ -225,6 +225,7 @@ bool WebPageData::applyChanges(
|
||||||
WebPageCollage &&newCollage,
|
WebPageCollage &&newCollage,
|
||||||
int newDuration,
|
int newDuration,
|
||||||
const QString &newAuthor,
|
const QString &newAuthor,
|
||||||
|
bool newHasLargeMedia,
|
||||||
int newPendingTill) {
|
int newPendingTill) {
|
||||||
if (newPendingTill != 0
|
if (newPendingTill != 0
|
||||||
&& (!url.isEmpty() || failed)
|
&& (!url.isEmpty() || failed)
|
||||||
|
@ -255,7 +256,6 @@ bool WebPageData::applyChanges(
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (type == newType
|
if (type == newType
|
||||||
&& hasLargeMedia == newHasLargeMedia
|
|
||||||
&& url == resultUrl
|
&& url == resultUrl
|
||||||
&& displayUrl == resultDisplayUrl
|
&& displayUrl == resultDisplayUrl
|
||||||
&& siteName == resultSiteName
|
&& siteName == resultSiteName
|
||||||
|
@ -267,6 +267,7 @@ bool WebPageData::applyChanges(
|
||||||
&& collage.items == newCollage.items
|
&& collage.items == newCollage.items
|
||||||
&& duration == newDuration
|
&& duration == newDuration
|
||||||
&& author == resultAuthor
|
&& author == resultAuthor
|
||||||
|
&& hasLargeMedia == (newHasLargeMedia ? 1 : 0)
|
||||||
&& pendingTill == newPendingTill) {
|
&& pendingTill == newPendingTill) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +275,7 @@ bool WebPageData::applyChanges(
|
||||||
_owner->session().api().clearWebPageRequest(this);
|
_owner->session().api().clearWebPageRequest(this);
|
||||||
}
|
}
|
||||||
type = newType;
|
type = newType;
|
||||||
hasLargeMedia = newHasLargeMedia;
|
hasLargeMedia = newHasLargeMedia ? 1 : 0;
|
||||||
url = resultUrl;
|
url = resultUrl;
|
||||||
displayUrl = resultDisplayUrl;
|
displayUrl = resultDisplayUrl;
|
||||||
siteName = resultSiteName;
|
siteName = resultSiteName;
|
||||||
|
@ -346,3 +347,11 @@ void WebPageData::ApplyChanges(
|
||||||
}
|
}
|
||||||
session->data().sendWebPageGamePollNotifications();
|
session->data().sendWebPageGamePollNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString WebPageData::displayedSiteName() const {
|
||||||
|
return (document && document->isWallPaper())
|
||||||
|
? tr::lng_media_chat_background(tr::now)
|
||||||
|
: (document && document->isTheme())
|
||||||
|
? tr::lng_media_color_theme(tr::now)
|
||||||
|
: siteName;
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ class Session;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
enum class WebPageType : uint8 {
|
enum class WebPageType : uint8 {
|
||||||
|
None,
|
||||||
|
|
||||||
Message,
|
Message,
|
||||||
|
|
||||||
Group,
|
Group,
|
||||||
|
@ -67,7 +69,6 @@ struct WebPageData {
|
||||||
|
|
||||||
bool applyChanges(
|
bool applyChanges(
|
||||||
WebPageType newType,
|
WebPageType newType,
|
||||||
bool newHasLargeMedia,
|
|
||||||
const QString &newUrl,
|
const QString &newUrl,
|
||||||
const QString &newDisplayUrl,
|
const QString &newDisplayUrl,
|
||||||
const QString &newSiteName,
|
const QString &newSiteName,
|
||||||
|
@ -79,6 +80,7 @@ struct WebPageData {
|
||||||
WebPageCollage &&newCollage,
|
WebPageCollage &&newCollage,
|
||||||
int newDuration,
|
int newDuration,
|
||||||
const QString &newAuthor,
|
const QString &newAuthor,
|
||||||
|
bool newHasLargeMedia,
|
||||||
int newPendingTill);
|
int newPendingTill);
|
||||||
|
|
||||||
static void ApplyChanges(
|
static void ApplyChanges(
|
||||||
|
@ -86,9 +88,10 @@ struct WebPageData {
|
||||||
ChannelData *channel,
|
ChannelData *channel,
|
||||||
const MTPmessages_Messages &result);
|
const MTPmessages_Messages &result);
|
||||||
|
|
||||||
WebPageId id = 0;
|
[[nodiscard]] QString displayedSiteName() const;
|
||||||
WebPageType type = WebPageType::Article;
|
|
||||||
bool hasLargeMedia = false;
|
const WebPageId id = 0;
|
||||||
|
WebPageType type = WebPageType::None;
|
||||||
QString url;
|
QString url;
|
||||||
QString displayUrl;
|
QString displayUrl;
|
||||||
QString siteName;
|
QString siteName;
|
||||||
|
@ -101,7 +104,8 @@ struct WebPageData {
|
||||||
WebPageCollage collage;
|
WebPageCollage collage;
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
TimeId pendingTill = 0;
|
TimeId pendingTill = 0;
|
||||||
uint32 version : 31 = 0;
|
uint32 version : 30 = 0;
|
||||||
|
uint32 hasLargeMedia : 1 = 0;
|
||||||
uint32 failed : 1 = 0;
|
uint32 failed : 1 = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1509,6 +1509,11 @@ void HistoryItem::applyEdition(HistoryMessageEdition &&edition) {
|
||||||
} else {
|
} else {
|
||||||
_flags &= ~MessageFlag::HideEdited;
|
_flags &= ~MessageFlag::HideEdited;
|
||||||
}
|
}
|
||||||
|
if (edition.invertMedia) {
|
||||||
|
_flags |= MessageFlag::InvertMedia;
|
||||||
|
} else {
|
||||||
|
_flags &= ~MessageFlag::InvertMedia;
|
||||||
|
}
|
||||||
|
|
||||||
if (edition.editDate != -1) {
|
if (edition.editDate != -1) {
|
||||||
//_flags |= MTPDmessage::Flag::f_edit_date;
|
//_flags |= MTPDmessage::Flag::f_edit_date;
|
||||||
|
|
|
@ -29,6 +29,7 @@ HistoryMessageEdition::HistoryMessageEdition(
|
||||||
if (const auto mtpReplies = message.vreplies()) {
|
if (const auto mtpReplies = message.vreplies()) {
|
||||||
replies = HistoryMessageRepliesData(mtpReplies);
|
replies = HistoryMessageRepliesData(mtpReplies);
|
||||||
}
|
}
|
||||||
|
invertMedia = message.is_invert_media();
|
||||||
|
|
||||||
const auto period = message.vttl_period();
|
const auto period = message.vttl_period();
|
||||||
ttl = (period && period->v > 0) ? (message.vdate().v + period->v) : 0;
|
ttl = (period && period->v > 0) ? (message.vdate().v + period->v) : 0;
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct HistoryMessageEdition {
|
||||||
bool useSameMarkup = false;
|
bool useSameMarkup = false;
|
||||||
bool useSameReactions = false;
|
bool useSameReactions = false;
|
||||||
bool savePreviousMedia = false;
|
bool savePreviousMedia = false;
|
||||||
|
bool invertMedia = false;
|
||||||
TextWithEntities textWithEntities;
|
TextWithEntities textWithEntities;
|
||||||
HistoryMessageMarkupData replyMarkup;
|
HistoryMessageMarkupData replyMarkup;
|
||||||
HistoryMessageRepliesData replies;
|
HistoryMessageRepliesData replies;
|
||||||
|
|
|
@ -2149,6 +2149,7 @@ void HistoryWidget::showHistory(
|
||||||
_photoEditMedia = nullptr;
|
_photoEditMedia = nullptr;
|
||||||
updateReplaceMediaButton();
|
updateReplaceMediaButton();
|
||||||
_previewData = nullptr;
|
_previewData = nullptr;
|
||||||
|
_previewDraft = {};
|
||||||
_previewCache.clear();
|
_previewCache.clear();
|
||||||
_fieldBarCancel->hide();
|
_fieldBarCancel->hide();
|
||||||
|
|
||||||
|
@ -3761,12 +3762,6 @@ void HistoryWidget::saveEditMsg() {
|
||||||
cancelEdit();
|
cancelEdit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto webPageId = _previewDraft.removed
|
|
||||||
? CancelledWebPageId
|
|
||||||
: (_previewData && !_previewData->failed)
|
|
||||||
? _previewData->id
|
|
||||||
: WebPageId();
|
|
||||||
|
|
||||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||||
const auto prepareFlags = Ui::ItemTextOptions(
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
_history,
|
_history,
|
||||||
|
@ -3833,10 +3828,10 @@ void HistoryWidget::saveEditMsg() {
|
||||||
};
|
};
|
||||||
|
|
||||||
auto options = Api::SendOptions();
|
auto options = Api::SendOptions();
|
||||||
options.removeWebPageId = (webPageId == CancelledWebPageId);
|
|
||||||
_saveEditMsgRequestId = Api::EditTextMessage(
|
_saveEditMsgRequestId = Api::EditTextMessage(
|
||||||
item,
|
item,
|
||||||
sending,
|
sending,
|
||||||
|
_previewDraft,
|
||||||
options,
|
options,
|
||||||
done,
|
done,
|
||||||
fail);
|
fail);
|
||||||
|
@ -3920,15 +3915,9 @@ void HistoryWidget::send(Api::SendOptions options) {
|
||||||
_cornerButtons.clearReplyReturns();
|
_cornerButtons.clearReplyReturns();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto webPageId = _previewDraft.removed
|
|
||||||
? CancelledWebPageId
|
|
||||||
: (_previewData && !_previewData->failed)
|
|
||||||
? _previewData->id
|
|
||||||
: WebPageId();
|
|
||||||
|
|
||||||
auto message = Api::MessageToSend(prepareSendAction(options));
|
auto message = Api::MessageToSend(prepareSendAction(options));
|
||||||
message.textWithTags = _field->getTextWithAppliedMarkdown();
|
message.textWithTags = _field->getTextWithAppliedMarkdown();
|
||||||
message.webPageId = webPageId;
|
message.webPage = _previewDraft;
|
||||||
|
|
||||||
const auto ignoreSlowmodeCountdown = (options.scheduled != 0);
|
const auto ignoreSlowmodeCountdown = (options.scheduled != 0);
|
||||||
if (showSendMessageError(
|
if (showSendMessageError(
|
||||||
|
@ -4338,23 +4327,23 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void HistoryWidget::updateOverStates(QPoint pos) {
|
void HistoryWidget::updateOverStates(QPoint pos) {
|
||||||
const auto isReadyToForward = readyToForward();
|
const auto isReadyToForward = readyToForward();
|
||||||
const auto skip = isReadyToForward ? 0 : st::historyReplySkip;
|
const auto skip = isReadyToForward ? 0 : st::historyReplySkip;
|
||||||
const auto replyEditForwardInfoRect = QRect(
|
const auto detailsRect = QRect(
|
||||||
skip,
|
skip,
|
||||||
_field->y() - st::historySendPadding - st::historyReplyHeight,
|
_field->y() - st::historySendPadding - st::historyReplyHeight,
|
||||||
width() - skip - _fieldBarCancel->width(),
|
width() - skip - _fieldBarCancel->width(),
|
||||||
st::historyReplyHeight);
|
st::historyReplyHeight);
|
||||||
auto inReplyEditForward = (_editMsgId || replyTo() || isReadyToForward)
|
const auto hasWebPage = _previewData && !_previewData->failed;
|
||||||
&& replyEditForwardInfoRect.contains(pos);
|
const auto inDetails = detailsRect.contains(pos)
|
||||||
auto inPhotoEdit = inReplyEditForward
|
&& (_editMsgId || replyTo() || isReadyToForward || hasWebPage);
|
||||||
|
const auto inPhotoEdit = inDetails
|
||||||
&& _photoEditMedia
|
&& _photoEditMedia
|
||||||
&& QRect(
|
&& QRect(
|
||||||
replyEditForwardInfoRect.x(),
|
detailsRect.x(),
|
||||||
(replyEditForwardInfoRect.y()
|
(detailsRect.y()
|
||||||
+ (replyEditForwardInfoRect.height()
|
+ (detailsRect.height() - st::historyReplyPreview) / 2),
|
||||||
- st::historyReplyPreview) / 2),
|
|
||||||
st::historyReplyPreview,
|
st::historyReplyPreview,
|
||||||
st::historyReplyPreview).contains(pos);
|
st::historyReplyPreview).contains(pos);
|
||||||
auto inClickable = inReplyEditForward;
|
const auto inClickable = inDetails;
|
||||||
if (_inPhotoEdit != inPhotoEdit) {
|
if (_inPhotoEdit != inPhotoEdit) {
|
||||||
_inPhotoEdit = inPhotoEdit;
|
_inPhotoEdit = inPhotoEdit;
|
||||||
if (_photoEditMedia) {
|
if (_photoEditMedia) {
|
||||||
|
@ -4367,7 +4356,7 @@ void HistoryWidget::updateOverStates(QPoint pos) {
|
||||||
_inPhotoEditOver.stop();
|
_inPhotoEditOver.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_inReplyEditForward = inReplyEditForward && !inPhotoEdit;
|
_inDetails = inDetails && !inPhotoEdit;
|
||||||
if (inClickable != _inClickable) {
|
if (inClickable != _inClickable) {
|
||||||
_inClickable = inClickable;
|
_inClickable = inClickable;
|
||||||
setCursor(_inClickable ? style::cur_pointer : style::cur_default);
|
setCursor(_inClickable ? style::cur_pointer : style::cur_default);
|
||||||
|
@ -4605,6 +4594,9 @@ bool HistoryWidget::showRecordButton() const {
|
||||||
&& !_voiceRecordBar->isListenState()
|
&& !_voiceRecordBar->isListenState()
|
||||||
&& !_voiceRecordBar->isRecordingByAnotherBar()
|
&& !_voiceRecordBar->isRecordingByAnotherBar()
|
||||||
&& !HasSendText(_field)
|
&& !HasSendText(_field)
|
||||||
|
&& (!_previewData
|
||||||
|
|| _previewData->failed
|
||||||
|
|| _previewData->pendingTill)
|
||||||
&& !readyToForward()
|
&& !readyToForward()
|
||||||
&& !_editMsgId;
|
&& !_editMsgId;
|
||||||
}
|
}
|
||||||
|
@ -6224,42 +6216,43 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
{ _history->peer->id, _editMsgId },
|
{ _history->peer->id, _editMsgId },
|
||||||
_field->getTextWithTags(),
|
_field->getTextWithTags(),
|
||||||
crl::guard(_list, [=] { cancelEdit(); }));
|
crl::guard(_list, [=] { cancelEdit(); }));
|
||||||
} else if (_inReplyEditForward) {
|
} else if (!_inDetails) {
|
||||||
if (isReadyToForward) {
|
return;
|
||||||
if (e->button() != Qt::LeftButton) {
|
} else if (_previewData
|
||||||
_forwardPanel->editToNextOption();
|
&& !_previewData->failed
|
||||||
} else {
|
&& !_previewData->pendingTill) {
|
||||||
_forwardPanel->editOptions(controller()->uiShow());
|
const auto history = _history;
|
||||||
}
|
using namespace HistoryView::Controls;
|
||||||
} else if (const auto reply = replyTo()) {
|
EditWebPageOptions(
|
||||||
const auto highlight = [=] {
|
controller()->uiShow(),
|
||||||
controller()->showPeerHistory(
|
_previewData,
|
||||||
reply.messageId.peer,
|
_previewDraft,
|
||||||
Window::SectionShow::Way::Forward,
|
[=](Data::WebPageDraft draft) { applyPreview(draft); });
|
||||||
reply.messageId.msg);
|
} else if (isReadyToForward) {
|
||||||
};
|
if (e->button() != Qt::LeftButton) {
|
||||||
const auto history = _history;
|
_forwardPanel->editToNextOption();
|
||||||
using namespace HistoryView::Controls;
|
} else {
|
||||||
EditReplyOptions(
|
_forwardPanel->editOptions(controller()->uiShow());
|
||||||
controller()->uiShow(),
|
|
||||||
reply,
|
|
||||||
highlight,
|
|
||||||
[=] { ClearDraftReplyTo(history, reply.messageId); });
|
|
||||||
} else if (_editMsgId) {
|
|
||||||
controller()->showPeerHistory(
|
|
||||||
_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);
|
|
||||||
}
|
}
|
||||||
|
} else if (const auto reply = replyTo()) {
|
||||||
|
const auto highlight = [=] {
|
||||||
|
controller()->showPeerHistory(
|
||||||
|
reply.messageId.peer,
|
||||||
|
Window::SectionShow::Way::Forward,
|
||||||
|
reply.messageId.msg);
|
||||||
|
};
|
||||||
|
const auto history = _history;
|
||||||
|
using namespace HistoryView::Controls;
|
||||||
|
EditReplyOptions(
|
||||||
|
controller()->uiShow(),
|
||||||
|
reply,
|
||||||
|
highlight,
|
||||||
|
[=] { ClearDraftReplyTo(history, reply.messageId); });
|
||||||
|
} else if (_editMsgId) {
|
||||||
|
controller()->showPeerHistory(
|
||||||
|
_peer,
|
||||||
|
Window::SectionShow::Way::Forward,
|
||||||
|
_editMsgId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7073,8 +7066,10 @@ void HistoryWidget::setFieldText(
|
||||||
_textUpdateEvents = TextUpdateEvent::SaveDraft
|
_textUpdateEvents = TextUpdateEvent::SaveDraft
|
||||||
| TextUpdateEvent::SendTyping;
|
| TextUpdateEvent::SendTyping;
|
||||||
|
|
||||||
previewCancel();
|
if (!_previewDraft.manual) {
|
||||||
_previewDraft = {};
|
previewCancel();
|
||||||
|
_previewDraft = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::clearFieldText(
|
void HistoryWidget::clearFieldText(
|
||||||
|
@ -7424,12 +7419,7 @@ void HistoryWidget::cancelFieldAreaState() {
|
||||||
controller()->hideLayer();
|
controller()->hideLayer();
|
||||||
_replyForwardPressed = false;
|
_replyForwardPressed = false;
|
||||||
if (_previewData && !_previewData->failed) {
|
if (_previewData && !_previewData->failed) {
|
||||||
_previewDraft = { .removed = true };
|
applyPreview({ .removed = true });
|
||||||
previewCancel();
|
|
||||||
|
|
||||||
_saveDraftText = true;
|
|
||||||
_saveDraftStart = crl::now();
|
|
||||||
saveDraft();
|
|
||||||
} else if (_editMsgId) {
|
} else if (_editMsgId) {
|
||||||
cancelEdit();
|
cancelEdit();
|
||||||
} else if (readyToForward()) {
|
} else if (readyToForward()) {
|
||||||
|
@ -7441,6 +7431,20 @@ void HistoryWidget::cancelFieldAreaState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::applyPreview(Data::WebPageDraft draft) {
|
||||||
|
_previewDraft = draft;
|
||||||
|
if (draft.removed) {
|
||||||
|
previewCancel();
|
||||||
|
} else if (draft.id) {
|
||||||
|
_previewData = session().data().webpage(draft.id).get();
|
||||||
|
requestPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveDraftText = true;
|
||||||
|
_saveDraftStart = crl::now();
|
||||||
|
saveDraft();
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::previewCancel() {
|
void HistoryWidget::previewCancel() {
|
||||||
_api.request(base::take(_previewRequest)).cancel();
|
_api.request(base::take(_previewRequest)).cancel();
|
||||||
_previewData = nullptr;
|
_previewData = nullptr;
|
||||||
|
@ -7455,6 +7459,8 @@ void HistoryWidget::checkPreview() {
|
||||||
if (_previewDraft.removed || previewRestricted) {
|
if (_previewDraft.removed || previewRestricted) {
|
||||||
previewCancel();
|
previewCancel();
|
||||||
return;
|
return;
|
||||||
|
} else if (_previewDraft.manual) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const auto links = _parsedLinks.join(' ');
|
const auto links = _parsedLinks.join(' ');
|
||||||
if (_previewLinks != links) {
|
if (_previewLinks != links) {
|
||||||
|
@ -7476,6 +7482,8 @@ void HistoryWidget::checkPreview() {
|
||||||
}).send();
|
}).send();
|
||||||
} else if (i.value()) {
|
} else if (i.value()) {
|
||||||
_previewData = session().data().webpage(i.value());
|
_previewData = session().data().webpage(i.value());
|
||||||
|
_previewDraft.id = _previewData->id;
|
||||||
|
_previewDraft.url = _previewData->url;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
} else if (_previewData && !_previewData->failed) {
|
} else if (_previewData && !_previewData->failed) {
|
||||||
previewCancel();
|
previewCancel();
|
||||||
|
@ -7518,6 +7526,12 @@ void HistoryWidget::gotPreview(
|
||||||
_previewData = (page->id && !page->failed)
|
_previewData = (page->id && !page->failed)
|
||||||
? page.get()
|
? page.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
if (_previewData) {
|
||||||
|
_previewDraft.id = _previewData->id;
|
||||||
|
_previewDraft.url = _previewData->url;
|
||||||
|
} else {
|
||||||
|
_previewDraft = {};
|
||||||
|
}
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
session().data().sendWebPageGamePollNotifications();
|
session().data().sendWebPageGamePollNotifications();
|
||||||
|
@ -7525,6 +7539,7 @@ void HistoryWidget::gotPreview(
|
||||||
_previewCache.insert(links, 0);
|
_previewCache.insert(links, 0);
|
||||||
if (links == _previewLinks && !_previewDraft.removed) {
|
if (links == _previewLinks && !_previewDraft.removed) {
|
||||||
_previewData = nullptr;
|
_previewData = nullptr;
|
||||||
|
_previewDraft = {};
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,7 @@ private:
|
||||||
void startBotCommand();
|
void startBotCommand();
|
||||||
void hidePinnedMessage();
|
void hidePinnedMessage();
|
||||||
void cancelFieldAreaState();
|
void cancelFieldAreaState();
|
||||||
|
void applyPreview(Data::WebPageDraft draft);
|
||||||
void unblockUser();
|
void unblockUser();
|
||||||
void sendBotStartCommand();
|
void sendBotStartCommand();
|
||||||
void joinChannel();
|
void joinChannel();
|
||||||
|
@ -759,7 +760,7 @@ private:
|
||||||
object_ptr<Ui::InputField> _field;
|
object_ptr<Ui::InputField> _field;
|
||||||
base::unique_qptr<Ui::RpWidget> _fieldDisabled;
|
base::unique_qptr<Ui::RpWidget> _fieldDisabled;
|
||||||
Ui::Animations::Simple _inPhotoEditOver;
|
Ui::Animations::Simple _inPhotoEditOver;
|
||||||
bool _inReplyEditForward = false;
|
bool _inDetails = false;
|
||||||
bool _inPhotoEdit = false;
|
bool _inPhotoEdit = false;
|
||||||
bool _inClickable = false;
|
bool _inClickable = false;
|
||||||
|
|
||||||
|
|
|
@ -365,7 +365,7 @@ public:
|
||||||
[[nodiscard]] rpl::producer<FullMsgId> scrollToItemRequests() const;
|
[[nodiscard]] rpl::producer<FullMsgId> scrollToItemRequests() const;
|
||||||
[[nodiscard]] rpl::producer<> editPhotoRequests() const;
|
[[nodiscard]] rpl::producer<> editPhotoRequests() const;
|
||||||
[[nodiscard]] MessageToEdit queryToEdit();
|
[[nodiscard]] MessageToEdit queryToEdit();
|
||||||
[[nodiscard]] WebPageId webPageId() const;
|
[[nodiscard]] Data::WebPageDraft webPageDraft() const;
|
||||||
|
|
||||||
[[nodiscard]] FullReplyTo getDraftReply() const;
|
[[nodiscard]] FullReplyTo getDraftReply() const;
|
||||||
[[nodiscard]] rpl::producer<> editCancelled() const {
|
[[nodiscard]] rpl::producer<> editCancelled() const {
|
||||||
|
@ -399,6 +399,7 @@ private:
|
||||||
|
|
||||||
struct Preview {
|
struct Preview {
|
||||||
WebPageData *data = nullptr;
|
WebPageData *data = nullptr;
|
||||||
|
Data::WebPageDraft draft;
|
||||||
Ui::Text::String title;
|
Ui::Text::String title;
|
||||||
Ui::Text::String description;
|
Ui::Text::String description;
|
||||||
bool cancelled = false;
|
bool cancelled = false;
|
||||||
|
@ -958,8 +959,10 @@ bool FieldHeader::hasPreview() const {
|
||||||
return ShowWebPagePreview(_preview.data);
|
return ShowWebPagePreview(_preview.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPageId FieldHeader::webPageId() const {
|
Data::WebPageDraft FieldHeader::webPageDraft() const {
|
||||||
return hasPreview() ? _preview.data->id : CancelledWebPageId;
|
return hasPreview()
|
||||||
|
? Data::WebPageDraft{ .id = _preview.data->id }
|
||||||
|
: Data::WebPageDraft{ .removed = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
FullReplyTo FieldHeader::getDraftReply() const {
|
FullReplyTo FieldHeader::getDraftReply() const {
|
||||||
|
@ -1027,10 +1030,7 @@ MessageToEdit FieldHeader::queryToEdit() {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
.fullId = item->fullId(),
|
.fullId = item->fullId(),
|
||||||
.options = {
|
.options = { .scheduled = item->isScheduled() ? item->date() : 0 },
|
||||||
.scheduled = item->isScheduled() ? item->date() : 0,
|
|
||||||
.removeWebPageId = !hasPreview(),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3119,8 +3119,8 @@ void ComposeControls::initForwardProcess() {
|
||||||
updateForwarding();
|
updateForwarding();
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPageId ComposeControls::webPageId() const {
|
Data::WebPageDraft ComposeControls::webPageDraft() const {
|
||||||
return _header->webPageId();
|
return _header->webPageDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<Data::MessagePosition> ComposeControls::scrollRequests() const {
|
rpl::producer<Data::MessagePosition> ComposeControls::scrollRequests() const {
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct MessagePosition;
|
||||||
struct Draft;
|
struct Draft;
|
||||||
class DraftKey;
|
class DraftKey;
|
||||||
class PhotoMedia;
|
class PhotoMedia;
|
||||||
|
struct WebPageDraft;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
|
@ -207,7 +208,7 @@ public:
|
||||||
void tryProcessKeyInput(not_null<QKeyEvent*> e);
|
void tryProcessKeyInput(not_null<QKeyEvent*> e);
|
||||||
|
|
||||||
[[nodiscard]] TextWithTags getTextWithAppliedMarkdown() const;
|
[[nodiscard]] TextWithTags getTextWithAppliedMarkdown() const;
|
||||||
[[nodiscard]] WebPageId webPageId() const;
|
[[nodiscard]] Data::WebPageDraft webPageDraft() const;
|
||||||
void setText(const TextWithTags &text);
|
void setText(const TextWithTags &text);
|
||||||
void clear();
|
void clear();
|
||||||
void hidePanelsAnimated();
|
void hidePanelsAnimated();
|
||||||
|
|
|
@ -547,4 +547,87 @@ void EditReplyOptions(
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditWebPageOptions(
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<WebPageData*> webpage,
|
||||||
|
Data::WebPageDraft draft,
|
||||||
|
Fn<void(Data::WebPageDraft)> done) {
|
||||||
|
show->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
|
box->setTitle(rpl::single(u"Link Preview"_q));
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
rpl::variable<Data::WebPageDraft> result;
|
||||||
|
Ui::SettingsButton *large = nullptr;
|
||||||
|
Ui::SettingsButton *small = nullptr;
|
||||||
|
};
|
||||||
|
const auto state = box->lifetime().make_state<State>(State{
|
||||||
|
.result = draft,
|
||||||
|
});
|
||||||
|
|
||||||
|
state->large = Settings::AddButton(
|
||||||
|
box->verticalLayout(),
|
||||||
|
rpl::single(u"Force large media"_q),
|
||||||
|
st::settingsButton,
|
||||||
|
{ &st::menuIconMakeBig });
|
||||||
|
state->large->setClickedCallback([=] {
|
||||||
|
auto copy = state->result.current();
|
||||||
|
copy.forceLargeMedia = true;
|
||||||
|
copy.forceSmallMedia = false;
|
||||||
|
state->result = copy;
|
||||||
|
});
|
||||||
|
|
||||||
|
state->small = Settings::AddButton(
|
||||||
|
box->verticalLayout(),
|
||||||
|
rpl::single(u"Force small media"_q),
|
||||||
|
st::settingsButton,
|
||||||
|
{ &st::menuIconMakeSmall });
|
||||||
|
state->small->setClickedCallback([=] {
|
||||||
|
auto copy = state->result.current();
|
||||||
|
copy.forceSmallMedia = true;
|
||||||
|
copy.forceLargeMedia = false;
|
||||||
|
state->result = copy;
|
||||||
|
});
|
||||||
|
|
||||||
|
state->result.value(
|
||||||
|
) | rpl::start_with_next([=](const Data::WebPageDraft &draft) {
|
||||||
|
state->large->setColorOverride(draft.forceLargeMedia
|
||||||
|
? st::windowActiveTextFg->c
|
||||||
|
: std::optional<QColor>());
|
||||||
|
state->small->setColorOverride(draft.forceSmallMedia
|
||||||
|
? st::windowActiveTextFg->c
|
||||||
|
: std::optional<QColor>());
|
||||||
|
}, box->lifetime());
|
||||||
|
|
||||||
|
Settings::AddButton(
|
||||||
|
box->verticalLayout(),
|
||||||
|
state->result.value(
|
||||||
|
) | rpl::map([=](const Data::WebPageDraft &draft) {
|
||||||
|
return draft.invert
|
||||||
|
? u"Above message"_q
|
||||||
|
: u"Below message"_q;
|
||||||
|
}),
|
||||||
|
st::settingsButton,
|
||||||
|
{ &st::menuIconChangeOrder }
|
||||||
|
)->setClickedCallback([=] {
|
||||||
|
auto copy = state->result.current();
|
||||||
|
copy.invert = !copy.invert;
|
||||||
|
state->result = copy;
|
||||||
|
});
|
||||||
|
|
||||||
|
box->addButton(tr::lng_settings_save(), [=] {
|
||||||
|
const auto weak = Ui::MakeWeak(box.get());
|
||||||
|
auto result = state->result.current();
|
||||||
|
result.manual = true;
|
||||||
|
done(result);
|
||||||
|
if (const auto strong = weak.data()) {
|
||||||
|
strong->closeBox();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
box->addButton(tr::lng_cancel(), [=] {
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace HistoryView::Controls
|
} // namespace HistoryView::Controls
|
||||||
|
|
|
@ -20,6 +20,7 @@ class SpoilerAnimation;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class Thread;
|
class Thread;
|
||||||
|
struct WebPageDraft;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -88,4 +89,10 @@ void EditReplyOptions(
|
||||||
Fn<void()> highlight,
|
Fn<void()> highlight,
|
||||||
Fn<void()> clearOldDraft = nullptr);
|
Fn<void()> clearOldDraft = nullptr);
|
||||||
|
|
||||||
|
void EditWebPageOptions(
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<WebPageData*> webpage,
|
||||||
|
Data::WebPageDraft draft,
|
||||||
|
Fn<void(Data::WebPageDraft)> done);
|
||||||
|
|
||||||
} // namespace HistoryView::Controls
|
} // namespace HistoryView::Controls
|
||||||
|
|
|
@ -539,9 +539,6 @@ bool AddRescheduleAction(
|
||||||
if (!item || !item->isScheduled()) {
|
if (!item || !item->isScheduled()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!item->media() || !item->media()->webpage()) {
|
|
||||||
options.removeWebPageId = true;
|
|
||||||
}
|
|
||||||
Api::RescheduleMessage(item, options);
|
Api::RescheduleMessage(item, options);
|
||||||
// Increase the scheduled date by 1s to keep the order.
|
// Increase the scheduled date by 1s to keep the order.
|
||||||
options.scheduled += 1;
|
options.scheduled += 1;
|
||||||
|
|
|
@ -2568,25 +2568,38 @@ void Message::updatePressed(QPoint point) {
|
||||||
TextForMimeData Message::selectedText(TextSelection selection) const {
|
TextForMimeData Message::selectedText(TextSelection selection) const {
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
auto logEntryOriginalResult = TextForMimeData();
|
auto logEntryOriginalResult = TextForMimeData();
|
||||||
|
const auto mediaDisplayed = (media && media->isDisplayed());
|
||||||
|
const auto textSelection = (mediaDisplayed && invertMedia())
|
||||||
|
? media->skipSelection(selection)
|
||||||
|
: selection;
|
||||||
|
const auto mediaSelection = !invertMedia()
|
||||||
|
? skipTextSelection(selection)
|
||||||
|
: selection;
|
||||||
auto textResult = hasVisibleText()
|
auto textResult = hasVisibleText()
|
||||||
? text().toTextForMimeData(selection)
|
? text().toTextForMimeData(textSelection)
|
||||||
: TextForMimeData();
|
: TextForMimeData();
|
||||||
auto skipped = skipTextSelection(selection);
|
|
||||||
auto mediaDisplayed = (media && media->isDisplayed());
|
|
||||||
auto mediaResult = (mediaDisplayed || isHiddenByGroup())
|
auto mediaResult = (mediaDisplayed || isHiddenByGroup())
|
||||||
? media->selectedText(skipped)
|
? media->selectedText(mediaSelection)
|
||||||
: TextForMimeData();
|
: TextForMimeData();
|
||||||
if (auto entry = logEntryOriginal()) {
|
if (auto entry = logEntryOriginal()) {
|
||||||
const auto originalSelection = mediaDisplayed
|
const auto originalSelection = (mediaDisplayed && invertMedia())
|
||||||
? media->skipSelection(skipped)
|
? skipTextSelection(textSelection)
|
||||||
: skipped;
|
: mediaDisplayed
|
||||||
|
? media->skipSelection(mediaSelection)
|
||||||
|
: skipTextSelection(selection);
|
||||||
logEntryOriginalResult = entry->selectedText(originalSelection);
|
logEntryOriginalResult = entry->selectedText(originalSelection);
|
||||||
}
|
}
|
||||||
auto result = textResult;
|
auto &first = (mediaDisplayed && invertMedia())
|
||||||
|
? mediaResult
|
||||||
|
: textResult;
|
||||||
|
auto &second = (mediaDisplayed && invertMedia())
|
||||||
|
? textResult
|
||||||
|
: mediaResult;
|
||||||
|
auto result = first;
|
||||||
if (result.empty()) {
|
if (result.empty()) {
|
||||||
result = std::move(mediaResult);
|
result = std::move(second);
|
||||||
} else if (!mediaResult.empty()) {
|
} else if (!second.empty()) {
|
||||||
result.append(u"\n\n"_q).append(std::move(mediaResult));
|
result.append(u"\n\n"_q).append(std::move(second));
|
||||||
}
|
}
|
||||||
if (result.empty()) {
|
if (result.empty()) {
|
||||||
result = std::move(logEntryOriginalResult);
|
result = std::move(logEntryOriginalResult);
|
||||||
|
|
|
@ -1170,11 +1170,9 @@ void RepliesWidget::send(Api::SendOptions options) {
|
||||||
_cornerButtons.clearReplyReturns();
|
_cornerButtons.clearReplyReturns();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto webPageId = _composeControls->webPageId();
|
|
||||||
|
|
||||||
auto message = Api::MessageToSend(prepareSendAction(options));
|
auto message = Api::MessageToSend(prepareSendAction(options));
|
||||||
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
message.webPageId = webPageId;
|
message.webPage = _composeControls->webPageDraft();
|
||||||
|
|
||||||
const auto error = GetErrorTextForSending(
|
const auto error = GetErrorTextForSending(
|
||||||
_history->peer,
|
_history->peer,
|
||||||
|
@ -1213,6 +1211,7 @@ void RepliesWidget::edit(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
|
const auto webpage = _composeControls->webPageDraft();
|
||||||
const auto prepareFlags = Ui::ItemTextOptions(
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
_history,
|
_history,
|
||||||
session().user()).flags;
|
session().user()).flags;
|
||||||
|
@ -1274,6 +1273,7 @@ void RepliesWidget::edit(
|
||||||
*saveEditMsgRequestId = Api::EditTextMessage(
|
*saveEditMsgRequestId = Api::EditTextMessage(
|
||||||
item,
|
item,
|
||||||
sending,
|
sending,
|
||||||
|
webpage,
|
||||||
options,
|
options,
|
||||||
crl::guard(this, done),
|
crl::guard(this, done),
|
||||||
crl::guard(this, fail));
|
crl::guard(this, fail));
|
||||||
|
|
|
@ -585,11 +585,11 @@ void ScheduledWidget::send() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduledWidget::send(Api::SendOptions options) {
|
void ScheduledWidget::send(Api::SendOptions options) {
|
||||||
const auto webPageId = _composeControls->webPageId();
|
const auto webPageDraft = _composeControls->webPageDraft();
|
||||||
|
|
||||||
auto message = Api::MessageToSend(prepareSendAction(options));
|
auto message = Api::MessageToSend(prepareSendAction(options));
|
||||||
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
message.webPageId = webPageId;
|
message.webPage = webPageDraft;
|
||||||
|
|
||||||
session().api().sendMessage(std::move(message));
|
session().api().sendMessage(std::move(message));
|
||||||
|
|
||||||
|
@ -635,6 +635,7 @@ void ScheduledWidget::edit(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
const auto textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
|
const auto webpage = _composeControls->webPageDraft();
|
||||||
const auto prepareFlags = Ui::ItemTextOptions(
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
_history,
|
_history,
|
||||||
session().user()).flags;
|
session().user()).flags;
|
||||||
|
@ -696,6 +697,7 @@ void ScheduledWidget::edit(
|
||||||
*saveEditMsgRequestId = Api::EditTextMessage(
|
*saveEditMsgRequestId = Api::EditTextMessage(
|
||||||
item,
|
item,
|
||||||
sending,
|
sending,
|
||||||
|
webpage,
|
||||||
options,
|
options,
|
||||||
crl::guard(this, done),
|
crl::guard(this, done),
|
||||||
crl::guard(this, fail));
|
crl::guard(this, fail));
|
||||||
|
|
|
@ -308,11 +308,12 @@ QSize WebPage::countOptimalSize() {
|
||||||
Ui::WebpageTextDescriptionOptions(),
|
Ui::WebpageTextDescriptionOptions(),
|
||||||
context);
|
context);
|
||||||
}
|
}
|
||||||
if (!displayedSiteName().isEmpty()) {
|
const auto siteName = _data->displayedSiteName();
|
||||||
|
if (!siteName.isEmpty()) {
|
||||||
_siteNameLines = 1;
|
_siteNameLines = 1;
|
||||||
_siteName.setMarkedText(
|
_siteName.setMarkedText(
|
||||||
st::webPageTitleStyle,
|
st::webPageTitleStyle,
|
||||||
Ui::Text::Link(displayedSiteName(), _data->url),
|
Ui::Text::Link(siteName, _data->url),
|
||||||
Ui::WebpageTextTitleOptions());
|
Ui::WebpageTextTitleOptions());
|
||||||
}
|
}
|
||||||
if (_title.isEmpty() && !title.isEmpty()) {
|
if (_title.isEmpty() && !title.isEmpty()) {
|
||||||
|
@ -868,6 +869,10 @@ TextSelection WebPage::adjustSelection(TextSelection selection, TextSelectType t
|
||||||
return { siteNameSelection.from, fromDescriptionSelection(descriptionSelection).to };
|
return { siteNameSelection.from, fromDescriptionSelection(descriptionSelection).to };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 WebPage::fullSelectionLength() const {
|
||||||
|
return _siteName.length() + _title.length() + _description.length();
|
||||||
|
}
|
||||||
|
|
||||||
void WebPage::clickHandlerActiveChanged(
|
void WebPage::clickHandlerActiveChanged(
|
||||||
const ClickHandlerPtr &p,
|
const ClickHandlerPtr &p,
|
||||||
bool active) {
|
bool active) {
|
||||||
|
@ -994,14 +999,6 @@ int WebPage::bottomInfoPadding() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WebPage::displayedSiteName() const {
|
|
||||||
return (_data->document && _data->document->isWallPaper())
|
|
||||||
? tr::lng_media_chat_background(tr::now)
|
|
||||||
: (_data->document && _data->document->isTheme())
|
|
||||||
? tr::lng_media_color_theme(tr::now)
|
|
||||||
: _data->siteName;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebPage::~WebPage() {
|
WebPage::~WebPage() {
|
||||||
history()->owner().unregisterWebPageView(_data, _parent);
|
history()->owner().unregisterWebPageView(_data, _parent);
|
||||||
if (_photoMedia) {
|
if (_photoMedia) {
|
||||||
|
|
|
@ -41,9 +41,7 @@ public:
|
||||||
[[nodiscard]] TextSelection adjustSelection(
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TextSelectType type) const override;
|
TextSelectType type) const override;
|
||||||
uint16 fullSelectionLength() const override {
|
uint16 fullSelectionLength() const override;
|
||||||
return _title.length() + _description.length();
|
|
||||||
}
|
|
||||||
bool hasTextForCopy() const override {
|
bool hasTextForCopy() const override {
|
||||||
// We do not add _title and _description in FullSelection text copy.
|
// We do not add _title and _description in FullSelection text copy.
|
||||||
return false;
|
return false;
|
||||||
|
@ -119,7 +117,6 @@ private:
|
||||||
[[nodiscard]] int bottomInfoPadding() const;
|
[[nodiscard]] int bottomInfoPadding() const;
|
||||||
[[nodiscard]] bool isLogEntryOriginal() const;
|
[[nodiscard]] bool isLogEntryOriginal() const;
|
||||||
|
|
||||||
[[nodiscard]] QString displayedSiteName() const;
|
|
||||||
[[nodiscard]] ClickHandlerPtr replaceAttachLink(
|
[[nodiscard]] ClickHandlerPtr replaceAttachLink(
|
||||||
const ClickHandlerPtr &link) const;
|
const ClickHandlerPtr &link) const;
|
||||||
[[nodiscard]] bool asArticle() const;
|
[[nodiscard]] bool asArticle() const;
|
||||||
|
|
|
@ -193,11 +193,11 @@ void ReplyArea::sendReaction(const Data::ReactionId &id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyArea::send(Api::SendOptions options) {
|
void ReplyArea::send(Api::SendOptions options) {
|
||||||
const auto webPageId = _controls->webPageId();
|
const auto webPageDraft = _controls->webPageDraft();
|
||||||
|
|
||||||
auto message = Api::MessageToSend(prepareSendAction(options));
|
auto message = Api::MessageToSend(prepareSendAction(options));
|
||||||
message.textWithTags = _controls->getTextWithAppliedMarkdown();
|
message.textWithTags = _controls->getTextWithAppliedMarkdown();
|
||||||
message.webPageId = webPageId;
|
message.webPage = webPageDraft;
|
||||||
|
|
||||||
send(std::move(message), options);
|
send(std::move(message), options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,3 +202,7 @@ mediaSpeedVeryFast: icon {{ "player/speed/audiospeed_menu_1.7", mediaviewMenuFg
|
||||||
mediaSpeedVeryFastActive: icon {{ "player/speed/audiospeed_menu_1.7", mediaviewTextLinkFg }};
|
mediaSpeedVeryFastActive: icon {{ "player/speed/audiospeed_menu_1.7", mediaviewTextLinkFg }};
|
||||||
mediaSpeedSuperFast: icon {{ "player/speed/audiospeed_menu_2.0", mediaviewMenuFg }};
|
mediaSpeedSuperFast: icon {{ "player/speed/audiospeed_menu_2.0", mediaviewMenuFg }};
|
||||||
mediaSpeedSuperFastActive: icon {{ "player/speed/audiospeed_menu_2.0", mediaviewTextLinkFg }};
|
mediaSpeedSuperFastActive: icon {{ "player/speed/audiospeed_menu_2.0", mediaviewTextLinkFg }};
|
||||||
|
|
||||||
|
menuIconMakeBig: icon {{ "player/player_fullscreen", menuIconColor }};
|
||||||
|
menuIconMakeSmall: icon {{ "player/player_minimize", menuIconColor }};
|
||||||
|
menuIconChangeOrder: icon {{ "player/player_order", menuIconColor }};
|
||||||
|
|
Loading…
Add table
Reference in a new issue