tdesktop/Telegram/SourceFiles/boxes/url_auth_box.cpp

313 lines
8.7 KiB
C++
Raw Normal View History

2019-05-22 14:29:02 +00:00
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/url_auth_box.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_components.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "core/click_handler_types.h"
#include "ui/text/text_utilities.h"
2019-05-22 14:29:02 +00:00
#include "ui/wrap/vertical_layout.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "lang/lang_keys.h"
2019-07-24 11:45:24 +00:00
#include "main/main_session.h"
2019-05-22 14:29:02 +00:00
#include "apiwrap.h"
2019-09-18 11:19:05 +00:00
#include "styles/style_layers.h"
2019-05-22 14:29:02 +00:00
#include "styles/style_boxes.h"
void UrlAuthBox::Activate(
not_null<const HistoryItem*> message,
int row,
int column) {
const auto itemId = message->fullId();
2020-06-08 15:17:33 +00:00
const auto button = HistoryMessageMarkupButton::Get(
&message->history()->owner(),
itemId,
row,
column);
if (button->requestId || !message->isRegular()) {
2019-05-22 14:29:02 +00:00
return;
}
const auto session = &message->history()->session();
const auto inputPeer = message->history()->peer->input;
const auto buttonId = button->buttonId;
const auto url = QString::fromUtf8(button->data);
2021-03-03 15:29:33 +00:00
using Flag = MTPmessages_RequestUrlAuth::Flag;
2019-05-22 14:29:02 +00:00
button->requestId = session->api().request(MTPmessages_RequestUrlAuth(
2021-03-03 15:29:33 +00:00
MTP_flags(Flag::f_peer | Flag::f_msg_id | Flag::f_button_id),
2019-05-22 14:29:02 +00:00
inputPeer,
MTP_int(itemId.msg),
2021-03-03 15:29:33 +00:00
MTP_int(buttonId),
MTPstring() // #TODO auth url
2019-05-22 14:29:02 +00:00
)).done([=](const MTPUrlAuthResult &result) {
const auto button = HistoryMessageMarkupButton::Get(
2020-06-08 15:17:33 +00:00
&session->data(),
2019-05-22 14:29:02 +00:00
itemId,
row,
column);
2020-06-08 15:17:33 +00:00
if (!button) {
return;
}
2019-05-22 14:29:02 +00:00
button->requestId = 0;
result.match([&](const MTPDurlAuthResultAccepted &data) {
2019-07-05 13:38:38 +00:00
UrlClickHandler::Open(qs(data.vurl()));
2019-05-22 14:29:02 +00:00
}, [&](const MTPDurlAuthResultDefault &data) {
HiddenUrlClickHandler::Open(url);
}, [&](const MTPDurlAuthResultRequest &data) {
if (const auto item = session->data().message(itemId)) {
Request(data, item, row, column);
}
2019-05-22 14:29:02 +00:00
});
}).fail([=] {
2019-05-22 14:29:02 +00:00
const auto button = HistoryMessageMarkupButton::Get(
2020-06-08 15:17:33 +00:00
&session->data(),
2019-05-22 14:29:02 +00:00
itemId,
row,
column);
if (!button) return;
button->requestId = 0;
HiddenUrlClickHandler::Open(url);
}).send();
}
void UrlAuthBox::Activate(
not_null<Main::Session*> session,
const QString &url,
QVariant context) {
context = QVariant::fromValue([&] {
auto result = context.value<ClickHandlerContext>();
result.skipBotAutoLogin = true;
return result;
}());
using Flag = MTPmessages_RequestUrlAuth::Flag;
session->api().request(MTPmessages_RequestUrlAuth(
MTP_flags(Flag::f_url),
MTPInputPeer(),
MTPint(), // msg_id
MTPint(), // button_id
MTP_string(url)
)).done([=](const MTPUrlAuthResult &result) {
result.match([&](const MTPDurlAuthResultAccepted &data) {
UrlClickHandler::Open(qs(data.vurl()), context);
}, [&](const MTPDurlAuthResultDefault &data) {
HiddenUrlClickHandler::Open(url, context);
}, [&](const MTPDurlAuthResultRequest &data) {
Request(data, session, url, context);
});
}).fail([=] {
HiddenUrlClickHandler::Open(url, context);
}).send();
}
2019-05-22 14:29:02 +00:00
void UrlAuthBox::Request(
const MTPDurlAuthResultRequest &request,
not_null<const HistoryItem*> message,
int row,
int column) {
const auto itemId = message->fullId();
2020-06-08 15:17:33 +00:00
const auto button = HistoryMessageMarkupButton::Get(
&message->history()->owner(),
itemId,
row,
column);
if (button->requestId || !message->isRegular()) {
2019-05-22 14:29:02 +00:00
return;
}
const auto session = &message->history()->session();
const auto inputPeer = message->history()->peer->input;
const auto buttonId = button->buttonId;
const auto url = QString::fromUtf8(button->data);
const auto bot = request.is_request_write_access()
2019-07-05 13:38:38 +00:00
? session->data().processUser(request.vbot()).get()
2019-05-22 14:29:02 +00:00
: nullptr;
2019-09-18 11:19:05 +00:00
const auto box = std::make_shared<QPointer<Ui::BoxContent>>();
2019-05-22 14:29:02 +00:00
const auto finishWithUrl = [=](const QString &url) {
if (*box) {
(*box)->closeBox();
}
UrlClickHandler::Open(url);
};
const auto callback = [=](Result result) {
if (result == Result::None) {
finishWithUrl(url);
} else if (const auto msg = session->data().message(itemId)) {
const auto allowWrite = (result == Result::AuthAndAllowWrite);
using Flag = MTPmessages_AcceptUrlAuth::Flag;
2021-03-03 15:29:33 +00:00
const auto flags = (allowWrite ? Flag::f_write_allowed : Flag(0))
| (Flag::f_peer | Flag::f_msg_id | Flag::f_button_id);
2019-05-22 14:29:02 +00:00
session->api().request(MTPmessages_AcceptUrlAuth(
2021-03-03 15:29:33 +00:00
MTP_flags(flags),
2019-05-22 14:29:02 +00:00
inputPeer,
MTP_int(itemId.msg),
2021-03-03 15:29:33 +00:00
MTP_int(buttonId),
MTPstring() // #TODO auth url
2019-05-22 14:29:02 +00:00
)).done([=](const MTPUrlAuthResult &result) {
const auto to = result.match(
[&](const MTPDurlAuthResultAccepted &data) {
2019-07-05 13:38:38 +00:00
return qs(data.vurl());
2019-05-22 14:29:02 +00:00
}, [&](const MTPDurlAuthResultDefault &data) {
return url;
}, [&](const MTPDurlAuthResultRequest &data) {
LOG(("API Error: "
"got urlAuthResultRequest after acceptUrlAuth."));
return url;
});
finishWithUrl(to);
}).fail([=] {
2019-05-22 14:29:02 +00:00
finishWithUrl(url);
}).send();
}
};
*box = Ui::show(
2019-08-06 16:40:08 +00:00
Box<UrlAuthBox>(session, url, qs(request.vdomain()), bot, callback),
2019-09-18 11:19:05 +00:00
Ui::LayerOption::KeepOther);
2019-05-22 14:29:02 +00:00
}
void UrlAuthBox::Request(
const MTPDurlAuthResultRequest &request,
not_null<Main::Session*> session,
const QString &url,
QVariant context) {
const auto bot = request.is_request_write_access()
? session->data().processUser(request.vbot()).get()
: nullptr;
const auto box = std::make_shared<QPointer<Ui::BoxContent>>();
const auto finishWithUrl = [=](const QString &url) {
if (*box) {
(*box)->closeBox();
}
UrlClickHandler::Open(url, context);
};
const auto callback = [=](Result result) {
if (result == Result::None) {
finishWithUrl(url);
} else {
const auto allowWrite = (result == Result::AuthAndAllowWrite);
using Flag = MTPmessages_AcceptUrlAuth::Flag;
const auto flags = (allowWrite ? Flag::f_write_allowed : Flag(0))
| Flag::f_url;
session->api().request(MTPmessages_AcceptUrlAuth(
MTP_flags(flags),
MTPInputPeer(),
MTPint(), // msg_id
MTPint(), // button_id
MTP_string(url)
)).done([=](const MTPUrlAuthResult &result) {
const auto to = result.match(
[&](const MTPDurlAuthResultAccepted &data) {
return qs(data.vurl());
}, [&](const MTPDurlAuthResultDefault &data) {
return url;
}, [&](const MTPDurlAuthResultRequest &data) {
LOG(("API Error: "
"got urlAuthResultRequest after acceptUrlAuth."));
return url;
});
finishWithUrl(to);
}).fail([=] {
finishWithUrl(url);
}).send();
}
};
*box = Ui::show(
Box<UrlAuthBox>(session, url, qs(request.vdomain()), bot, callback),
Ui::LayerOption::KeepOther);
}
2019-05-22 14:29:02 +00:00
UrlAuthBox::UrlAuthBox(
QWidget*,
2019-08-06 16:40:08 +00:00
not_null<Main::Session*> session,
2019-05-22 14:29:02 +00:00
const QString &url,
const QString &domain,
UserData *bot,
Fn<void(Result)> callback)
2019-08-06 16:40:08 +00:00
: _content(setupContent(session, url, domain, bot, std::move(callback))) {
2019-05-22 14:29:02 +00:00
}
void UrlAuthBox::prepare() {
setDimensionsToContent(st::boxWidth, _content);
addButton(tr::lng_open_link(), [=] { _callback(); });
addButton(tr::lng_cancel(), [=] { closeBox(); });
2019-05-22 14:29:02 +00:00
}
not_null<Ui::RpWidget*> UrlAuthBox::setupContent(
2019-08-06 16:40:08 +00:00
not_null<Main::Session*> session,
2019-05-22 14:29:02 +00:00
const QString &url,
const QString &domain,
UserData *bot,
Fn<void(Result)> callback) {
const auto result = Ui::CreateChild<Ui::VerticalLayout>(this);
result->add(
object_ptr<Ui::FlatLabel>(
result,
tr::lng_url_auth_open_confirm(tr::now, lt_link, url),
2019-05-22 14:29:02 +00:00
st::boxLabel),
st::boxPadding);
const auto addCheckbox = [&](const TextWithEntities &text) {
2019-05-22 14:29:02 +00:00
const auto checkbox = result->add(
object_ptr<Ui::Checkbox>(
result,
text,
true,
2019-05-22 14:29:02 +00:00
st::urlAuthCheckbox),
style::margins(
st::boxPadding.left(),
st::boxPadding.bottom(),
st::boxPadding.right(),
st::boxPadding.bottom()));
2019-09-04 15:59:43 +00:00
checkbox->setAllowTextLines();
2019-05-22 14:29:02 +00:00
return checkbox;
};
const auto auth = addCheckbox(
tr::lng_url_auth_login_option(
tr::now,
2019-05-22 14:29:02 +00:00
lt_domain,
Ui::Text::Bold(domain),
2019-05-22 14:29:02 +00:00
lt_user,
Ui::Text::Bold(session->user()->name),
Ui::Text::WithEntities));
2019-05-22 14:29:02 +00:00
const auto allow = bot
? addCheckbox(tr::lng_url_auth_allow_messages(
tr::now,
2019-05-22 14:29:02 +00:00
lt_bot,
Ui::Text::Bold(bot->firstName),
Ui::Text::WithEntities))
2019-05-22 14:29:02 +00:00
: nullptr;
if (allow) {
rpl::single(
auth->checked()
) | rpl::then(
auth->checkedChanges()
) | rpl::start_with_next([=](bool checked) {
if (!checked) {
allow->setChecked(false);
}
2019-05-22 14:29:02 +00:00
allow->setDisabled(!checked);
}, auth->lifetime());
}
_callback = [=, callback = std::move(callback)]() {
const auto authed = auth->checked();
const auto allowed = (authed && allow && allow->checked());
const auto onstack = callback;
onstack(allowed
? Result::AuthAndAllowWrite
: authed
? Result::Auth
: Result::None);
};
return result;
}