mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 06:35:14 +00:00
Add support for inline invoices.
This commit is contained in:
@@ -696,24 +696,24 @@ void Video::initDimensions() {
|
||||
const auto withThumb = withThumbnail();
|
||||
|
||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||
int32 textWidth = _maxw - (withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
|
||||
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
const auto textWidth = _maxw - (st::inlineThumbSize + st::inlineThumbSkip);
|
||||
TextParseOptions titleOpts = { 0, textWidth, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
auto title = TextUtilities::SingleLine(_result->getLayoutTitle());
|
||||
if (title.isEmpty()) {
|
||||
title = tr::lng_media_video(tr::now);
|
||||
}
|
||||
_title.setText(st::semiboldTextStyle, title, titleOpts);
|
||||
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
|
||||
int32 titleHeight = qMin(_title.countHeight(textWidth), 2 * st::semiboldFont->height);
|
||||
|
||||
int32 descriptionLines = withThumb ? (titleHeight > st::semiboldFont->height ? 1 : 2) : 3;
|
||||
|
||||
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
|
||||
TextParseOptions descriptionOpts = { TextParseMultiline, textWidth, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
|
||||
QString description = _result->getLayoutDescription();
|
||||
if (description.isEmpty()) {
|
||||
description = _duration;
|
||||
}
|
||||
_description.setText(st::defaultTextStyle, description, descriptionOpts);
|
||||
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
|
||||
int32 descriptionHeight = qMin(_description.countHeight(textWidth), descriptionLines * st::normalFont->height);
|
||||
|
||||
_minh = st::inlineThumbSize;
|
||||
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
|
||||
@@ -1073,13 +1073,13 @@ Contact::Contact(not_null<Context*> context, not_null<Result*> result)
|
||||
void Contact::initDimensions() {
|
||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||
int32 textWidth = _maxw - (st::inlineThumbSize + st::inlineThumbSkip);
|
||||
TextParseOptions titleOpts = { 0, _maxw, st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
TextParseOptions titleOpts = { 0, textWidth, st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
_title.setText(st::semiboldTextStyle, TextUtilities::SingleLine(_result->getLayoutTitle()), titleOpts);
|
||||
int32 titleHeight = qMin(_title.countHeight(_maxw), st::semiboldFont->height);
|
||||
int32 titleHeight = qMin(_title.countHeight(textWidth), st::semiboldFont->height);
|
||||
|
||||
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, st::normalFont->height, Qt::LayoutDirectionAuto };
|
||||
TextParseOptions descriptionOpts = { TextParseMultiline, textWidth, st::normalFont->height, Qt::LayoutDirectionAuto };
|
||||
_description.setText(st::defaultTextStyle, _result->getLayoutDescription(), descriptionOpts);
|
||||
int32 descriptionHeight = qMin(_description.countHeight(_maxw), st::normalFont->height);
|
||||
int32 descriptionHeight = qMin(_description.countHeight(textWidth), st::normalFont->height);
|
||||
|
||||
_minh = st::inlineFileSize;
|
||||
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
|
||||
@@ -1170,7 +1170,7 @@ Article::Article(
|
||||
|
||||
void Article::initDimensions() {
|
||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
|
||||
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : (st::emojiPanHeaderLeft - st::inlineResultsLeft));
|
||||
TextParseOptions titleOpts = { 0, textWidth, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
_title.setText(st::semiboldTextStyle, TextUtilities::SingleLine(_result->getLayoutTitle()), titleOpts);
|
||||
int32 titleHeight = qMin(_title.countHeight(textWidth), 2 * st::semiboldFont->height);
|
||||
@@ -1192,8 +1192,9 @@ int32 Article::resizeGetHeight(int32 width) {
|
||||
if (_url) {
|
||||
_urlText = getResultUrl();
|
||||
_urlWidth = st::normalFont->width(_urlText);
|
||||
if (_urlWidth > _width - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||
_urlText = st::normalFont->elided(_urlText, _width - st::inlineThumbSize - st::inlineThumbSkip);
|
||||
int32 textWidth = _width - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : (st::emojiPanHeaderLeft - st::inlineResultsLeft));
|
||||
if (_urlWidth > textWidth) {
|
||||
_urlText = st::normalFont->elided(_urlText, textWidth);
|
||||
_urlWidth = st::normalFont->width(_urlText);
|
||||
}
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ Result::Result(not_null<Main::Session*> session, const Creator &creator)
|
||||
std::unique_ptr<Result> Result::Create(
|
||||
not_null<Main::Session*> session,
|
||||
uint64 queryId,
|
||||
const MTPBotInlineResult &mtpData) {
|
||||
const MTPBotInlineResult &data) {
|
||||
using Type = Result::Type;
|
||||
|
||||
const auto type = [&] {
|
||||
@@ -69,7 +69,7 @@ std::unique_ptr<Result> Result::Create(
|
||||
{ u"geo"_q, Type::Geo },
|
||||
{ u"game"_q, Type::Game },
|
||||
};
|
||||
const auto type = mtpData.match([](const auto &data) {
|
||||
const auto type = data.match([](const auto &data) {
|
||||
return qs(data.vtype());
|
||||
});
|
||||
const auto i = kStringToTypeMap.find(type);
|
||||
@@ -82,16 +82,13 @@ std::unique_ptr<Result> Result::Create(
|
||||
auto result = std::make_unique<Result>(
|
||||
session,
|
||||
Creator{ queryId, type });
|
||||
const MTPBotInlineMessage *message = nullptr;
|
||||
switch (mtpData.type()) {
|
||||
case mtpc_botInlineResult: {
|
||||
const auto &r = mtpData.c_botInlineResult();
|
||||
result->_id = qs(r.vid());
|
||||
result->_title = qs(r.vtitle().value_or_empty());
|
||||
result->_description = qs(r.vdescription().value_or_empty());
|
||||
result->_url = qs(r.vurl().value_or_empty());
|
||||
const auto message = data.match([&](const MTPDbotInlineResult &data) {
|
||||
result->_id = qs(data.vid());
|
||||
result->_title = qs(data.vtitle().value_or_empty());
|
||||
result->_description = qs(data.vdescription().value_or_empty());
|
||||
result->_url = qs(data.vurl().value_or_empty());
|
||||
const auto thumbMime = [&] {
|
||||
if (const auto thumb = r.vthumb()) {
|
||||
if (const auto thumb = data.vthumb()) {
|
||||
return thumb->match([&](const auto &data) {
|
||||
return data.vmime_type().v;
|
||||
});
|
||||
@@ -99,7 +96,7 @@ std::unique_ptr<Result> Result::Create(
|
||||
return QByteArray();
|
||||
}();
|
||||
const auto contentMime = [&] {
|
||||
if (const auto content = r.vcontent()) {
|
||||
if (const auto content = data.vcontent()) {
|
||||
return content->match([&](const auto &data) {
|
||||
return data.vmime_type().v;
|
||||
});
|
||||
@@ -109,49 +106,45 @@ std::unique_ptr<Result> Result::Create(
|
||||
const auto imageThumb = !thumbMime.isEmpty()
|
||||
&& (thumbMime != kVideoThumbMime);
|
||||
const auto videoThumb = !thumbMime.isEmpty() && !imageThumb;
|
||||
if (const auto content = r.vcontent()) {
|
||||
if (const auto content = data.vcontent()) {
|
||||
result->_content_url = GetContentUrl(*content);
|
||||
if (result->_type == Type::Photo) {
|
||||
result->_photo = session->data().photoFromWeb(
|
||||
*content,
|
||||
(imageThumb
|
||||
? Images::FromWebDocument(*r.vthumb())
|
||||
? Images::FromWebDocument(*data.vthumb())
|
||||
: ImageLocation()));
|
||||
} else if (contentMime != "text/html"_q) {
|
||||
result->_document = session->data().documentFromWeb(
|
||||
result->adjustAttributes(*content),
|
||||
(imageThumb
|
||||
? Images::FromWebDocument(*r.vthumb())
|
||||
? Images::FromWebDocument(*data.vthumb())
|
||||
: ImageLocation()),
|
||||
(videoThumb
|
||||
? Images::FromWebDocument(*r.vthumb())
|
||||
? Images::FromWebDocument(*data.vthumb())
|
||||
: ImageLocation()));
|
||||
}
|
||||
}
|
||||
if (!result->_photo && !result->_document && imageThumb) {
|
||||
result->_thumbnail.update(result->_session, ImageWithLocation{
|
||||
.location = Images::FromWebDocument(*r.vthumb())
|
||||
});
|
||||
.location = Images::FromWebDocument(*data.vthumb())
|
||||
});
|
||||
}
|
||||
message = &r.vsend_message();
|
||||
} break;
|
||||
case mtpc_botInlineMediaResult: {
|
||||
const auto &r = mtpData.c_botInlineMediaResult();
|
||||
result->_id = qs(r.vid());
|
||||
result->_title = qs(r.vtitle().value_or_empty());
|
||||
result->_description = qs(r.vdescription().value_or_empty());
|
||||
if (const auto photo = r.vphoto()) {
|
||||
return &data.vsend_message();
|
||||
}, [&](const MTPDbotInlineMediaResult &data) {
|
||||
result->_id = qs(data.vid());
|
||||
result->_title = qs(data.vtitle().value_or_empty());
|
||||
result->_description = qs(data.vdescription().value_or_empty());
|
||||
if (const auto photo = data.vphoto()) {
|
||||
result->_photo = session->data().processPhoto(*photo);
|
||||
}
|
||||
if (const auto document = r.vdocument()) {
|
||||
if (const auto document = data.vdocument()) {
|
||||
result->_document = session->data().processDocument(*document);
|
||||
}
|
||||
message = &r.vsend_message();
|
||||
} break;
|
||||
}
|
||||
return &data.vsend_message();
|
||||
});
|
||||
if ((result->_photo && result->_photo->isNull())
|
||||
|| (result->_document && result->_document->isNull())
|
||||
|| !message) {
|
||||
|| (result->_document && result->_document->isNull())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -248,7 +241,23 @@ std::unique_ptr<Result> Result::Create(
|
||||
qs(data.vlast_name()),
|
||||
qs(data.vphone_number()));
|
||||
}, [&](const MTPDbotInlineMessageMediaInvoice &data) {
|
||||
// #TODO payments
|
||||
using Flag = MTPDmessageMediaInvoice::Flag;
|
||||
const auto media = MTP_messageMediaInvoice(
|
||||
MTP_flags((data.is_shipping_address_requested()
|
||||
? Flag::f_shipping_address_requested
|
||||
: Flag(0))
|
||||
| (data.is_test() ? Flag::f_test : Flag(0))
|
||||
| (data.vphoto() ? Flag::f_photo : Flag(0))),
|
||||
data.vtitle(),
|
||||
data.vdescription(),
|
||||
data.vphoto() ? (*data.vphoto()) : MTPWebDocument(),
|
||||
MTPint(), // receipt_msg_id
|
||||
data.vcurrency(),
|
||||
data.vtotal_amount(),
|
||||
MTP_string(QString())); // start_param
|
||||
result->sendData = std::make_unique<internal::SendInvoice>(
|
||||
session,
|
||||
media);
|
||||
});
|
||||
|
||||
if (!result->sendData || !result->sendData->isValid()) {
|
||||
|
@@ -264,5 +264,15 @@ QString SendGame::getErrorOnSend(
|
||||
return error.value_or(QString());
|
||||
}
|
||||
|
||||
auto SendInvoice::getSentMessageFields() const -> SentMTPMessageFields {
|
||||
SentMTPMessageFields result;
|
||||
result.media = _media;
|
||||
return result;
|
||||
}
|
||||
|
||||
QString SendInvoice::getLayoutDescription(const Result *owner) const {
|
||||
return qs(_media.c_messageMediaInvoice().vdescription());
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace InlineBots
|
||||
|
@@ -351,5 +351,27 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class SendInvoice : public SendDataCommon {
|
||||
public:
|
||||
SendInvoice(
|
||||
not_null<Main::Session*> session,
|
||||
MTPMessageMedia media)
|
||||
: SendDataCommon(session)
|
||||
, _media(media) {
|
||||
}
|
||||
|
||||
bool isValid() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
SentMTPMessageFields getSentMessageFields() const override;
|
||||
|
||||
QString getLayoutDescription(const Result *owner) const override;
|
||||
|
||||
private:
|
||||
MTPMessageMedia _media;
|
||||
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace InlineBots
|
||||
|
Reference in New Issue
Block a user