tdesktop/Telegram/SourceFiles/boxes/peers/edit_contact_box.cpp

255 lines
6.4 KiB
C++
Raw Normal View History

2019-06-10 15:47:22 +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
*/
2019-06-12 14:13:49 +00:00
#include "boxes/peers/edit_contact_box.h"
2019-06-10 15:47:22 +00:00
2019-06-12 14:13:49 +00:00
#include "boxes/generic_box.h"
2019-06-10 15:47:22 +00:00
#include "data/data_user.h"
#include "data/data_session.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/input_fields.h"
2019-06-12 13:26:04 +00:00
#include "ui/text/text_utilities.h"
2019-06-10 15:47:22 +00:00
#include "info/profile/info_profile_cover.h"
#include "lang/lang_keys.h"
#include "window/window_controller.h"
2019-06-12 13:26:04 +00:00
#include "ui/toast/toast.h"
2019-06-10 15:47:22 +00:00
#include "auth_session.h"
#include "apiwrap.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
namespace {
QString UserPhone(not_null<UserData*> user) {
const auto phone = user->phone();
return phone.isEmpty()
? user->owner().findContactPhone(user->bareId())
: phone;
}
class Controller {
2019-06-12 14:13:49 +00:00
public:
Controller(
2019-06-12 14:13:49 +00:00
not_null<GenericBox*> box,
not_null<Window::Controller*> window,
not_null<UserData*> user);
void prepare();
2019-06-12 14:13:49 +00:00
private:
void setupContent();
void setupCover();
void setupNameFields();
void setupWarning();
void setupSharePhoneNumber();
2019-06-12 14:13:49 +00:00
void initNameFields(
not_null<Ui::InputField*> first,
not_null<Ui::InputField*> last,
bool inverted);
void sendRequest(const QString &first, const QString &last);
2019-06-12 14:13:49 +00:00
not_null<GenericBox*> _box;
not_null<Window::Controller*> _window;
not_null<UserData*> _user;
Ui::Checkbox *_sharePhone = nullptr;
2019-06-12 14:13:49 +00:00
QString _phone;
Fn<void()> _focus;
Fn<void()> _save;
2019-06-10 15:47:22 +00:00
2019-06-12 14:13:49 +00:00
};
Controller::Controller(
2019-06-12 14:13:49 +00:00
not_null<GenericBox*> box,
2019-06-10 15:47:22 +00:00
not_null<Window::Controller*> window,
not_null<UserData*> user)
2019-06-12 14:13:49 +00:00
: _box(box)
, _window(window)
2019-06-10 15:47:22 +00:00
, _user(user)
, _phone(UserPhone(user)) {
}
void Controller::prepare() {
2019-06-10 15:47:22 +00:00
setupContent();
_box->setTitle(_user->isContact()
? tr::lng_edit_contact_title()
: tr::lng_enter_contact_data());
2019-06-10 15:47:22 +00:00
_box->addButton(tr::lng_box_done(), _save);
_box->addButton(tr::lng_cancel(), [=] { _box->closeBox(); });
_box->setFocusCallback(_focus);
2019-06-10 15:47:22 +00:00
}
void Controller::setupContent() {
2019-06-12 14:13:49 +00:00
setupCover();
setupNameFields();
setupWarning();
setupSharePhoneNumber();
2019-06-10 15:47:22 +00:00
}
void Controller::setupCover() {
2019-06-12 14:13:49 +00:00
_box->addRow(
object_ptr<Info::Profile::Cover>(
_box,
_user,
_window->sessionController(),
(_phone.isEmpty()
2019-06-18 12:16:43 +00:00
? tr::lng_contact_mobile_hidden()
2019-06-12 14:13:49 +00:00
: rpl::single(App::formatPhone(_phone)))),
style::margins())->setAttribute(Qt::WA_TransparentForMouseEvents);
2019-06-10 15:47:22 +00:00
}
void Controller::setupNameFields() {
2019-06-10 15:47:22 +00:00
const auto inverted = langFirstNameGoesSecond();
2019-06-12 14:13:49 +00:00
const auto first = _box->addRow(
2019-06-10 15:47:22 +00:00
object_ptr<Ui::InputField>(
2019-06-12 14:13:49 +00:00
_box,
2019-06-10 15:47:22 +00:00
st::defaultInputField,
tr::lng_signup_firstname(),
2019-06-10 15:47:22 +00:00
_user->firstName),
st::addContactFieldMargin);
auto preparedLast = object_ptr<Ui::InputField>(
2019-06-12 14:13:49 +00:00
_box,
2019-06-10 15:47:22 +00:00
st::defaultInputField,
tr::lng_signup_lastname(),
2019-06-10 15:47:22 +00:00
_user->lastName);
const auto last = inverted
2019-06-12 14:13:49 +00:00
? _box->insertRow(
_box->rowsCount() - 1,
2019-06-10 15:47:22 +00:00
std::move(preparedLast),
st::addContactFieldMargin)
2019-06-12 14:13:49 +00:00
: _box->addRow(std::move(preparedLast), st::addContactFieldMargin);
2019-06-10 15:47:22 +00:00
initNameFields(first, last, inverted);
}
void Controller::initNameFields(
2019-06-10 15:47:22 +00:00
not_null<Ui::InputField*> first,
not_null<Ui::InputField*> last,
bool inverted) {
2019-06-12 14:13:49 +00:00
const auto getValue = [](not_null<Ui::InputField*> field) {
return TextUtilities::SingleLine(field->getLastText()).trimmed();
2019-06-10 15:47:22 +00:00
};
2019-06-12 14:13:49 +00:00
if (inverted) {
_box->setTabOrder(last, first);
2019-06-12 14:13:49 +00:00
}
_focus = [=] {
2019-06-12 14:13:49 +00:00
const auto firstValue = getValue(first);
const auto lastValue = getValue(last);
2019-06-10 15:47:22 +00:00
const auto empty = firstValue.isEmpty() && lastValue.isEmpty();
const auto focusFirst = (inverted != empty);
(focusFirst ? first : last)->setFocusFast();
};
_save = [=] {
2019-06-12 14:13:49 +00:00
const auto firstValue = getValue(first);
const auto lastValue = getValue(last);
2019-06-10 15:47:22 +00:00
const auto empty = firstValue.isEmpty() && lastValue.isEmpty();
if (empty) {
_focus();
2019-06-10 15:47:22 +00:00
(inverted ? last : first)->showError();
return;
}
sendRequest(firstValue, lastValue);
2019-06-10 15:47:22 +00:00
};
2019-06-12 14:13:49 +00:00
const auto submit = [=] {
const auto firstValue = first->getLastText().trimmed();
const auto lastValue = last->getLastText().trimmed();
const auto empty = firstValue.isEmpty() && lastValue.isEmpty();
if (inverted ? last->hasFocus() : empty) {
first->setFocus();
} else if (inverted ? empty : first->hasFocus()) {
last->setFocus();
} else {
_save();
}
};
QObject::connect(first, &Ui::InputField::submitted, submit);
QObject::connect(last, &Ui::InputField::submitted, submit);
}
2019-06-12 14:13:49 +00:00
void Controller::sendRequest(const QString &first, const QString &last) {
const auto wasContact = _user->isContact();
const auto weak = make_weak(_box);
using Flag = MTPcontacts_AddContact::Flag;
_user->session().api().request(MTPcontacts_AddContact(
MTP_flags((_sharePhone && _sharePhone->checked())
? Flag::f_add_phone_privacy_exception
: Flag(0)),
_user->inputUser,
MTP_string(first),
MTP_string(last),
MTP_string(_phone)
)).done([=](const MTPUpdates &result) {
_user->setName(
first,
last,
_user->nameOrPhone,
_user->username);
_user->session().api().applyUpdates(result);
if (const auto settings = _user->settings()) {
using Flag = MTPDpeerSettings::Flag;
const auto flags = Flag::f_add_contact
| Flag::f_block_contact
| Flag::f_report_spam;
_user->setSettings(*settings & ~flags);
}
if (weak) {
weak->closeBox();
}
if (!wasContact) {
Ui::Toast::Show(lng_new_contact_add_done(lt_user, first));
}
}).fail([=](const RPCError &error) {
}).send();
2019-06-10 15:47:22 +00:00
}
void Controller::setupWarning() {
if (_user->isContact() || !_phone.isEmpty()) {
2019-06-12 14:13:49 +00:00
return;
}
_box->addRow(
2019-06-10 15:47:22 +00:00
object_ptr<Ui::FlatLabel>(
2019-06-12 14:13:49 +00:00
_box,
lng_contact_phone_after(lt_user, _user->shortName()),
2019-06-10 15:47:22 +00:00
st::changePhoneLabel),
st::addContactWarningMargin);
2019-06-12 14:13:49 +00:00
}
void Controller::setupSharePhoneNumber() {
const auto settings = _user->settings();
using Setting = MTPDpeerSettings::Flag;
if (!settings
|| !((*settings) & Setting::f_need_contacts_exception)) {
return;
}
_sharePhone = _box->addRow(
object_ptr<Ui::Checkbox>(
_box,
lang(lng_contact_share_phone),
true,
st::defaultBoxCheckbox),
st::addContactWarningMargin);
_box->addRow(
object_ptr<Ui::FlatLabel>(
_box,
lng_contact_phone_will_be_shared(lt_user, _user->shortName()),
st::changePhoneLabel),
st::addContactWarningMargin);
}
2019-06-12 14:13:49 +00:00
} // namespace
void EditContactBox(
not_null<GenericBox*> box,
not_null<Window::Controller*> window,
not_null<UserData*> user) {
box->lifetime().make_state<Controller>(box, window, user)->prepare();
2019-06-12 14:13:49 +00:00
}