mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Moved SentCodeField to td_ui.
This commit is contained in:
parent
94d5d20281
commit
c15ba7d23a
13 changed files with 267 additions and 210 deletions
|
@ -129,11 +129,11 @@ private:
|
||||||
QString _hash;
|
QString _hash;
|
||||||
int _codeLength = 0;
|
int _codeLength = 0;
|
||||||
int _callTimeout = 0;
|
int _callTimeout = 0;
|
||||||
object_ptr<SentCodeField> _code = { nullptr };
|
object_ptr<Ui::SentCodeField> _code = { nullptr };
|
||||||
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _error = { nullptr };
|
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _error = { nullptr };
|
||||||
object_ptr<Ui::FlatLabel> _callLabel = { nullptr };
|
object_ptr<Ui::FlatLabel> _callLabel = { nullptr };
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
SentCodeCall _call;
|
Ui::SentCodeCall _call;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ void ChangePhoneBox::EnterCode::prepare() {
|
||||||
setDimensions(st::boxWidth, countHeight());
|
setDimensions(st::boxWidth, countHeight());
|
||||||
|
|
||||||
if (_callTimeout > 0) {
|
if (_callTimeout > 0) {
|
||||||
_call.setStatus({ SentCodeCall::State::Waiting, _callTimeout });
|
_call.setStatus({ Ui::SentCodeCall::State::Waiting, _callTimeout });
|
||||||
updateCall();
|
updateCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,131 +70,6 @@ void ShowPhoneBannedError(const QString &phone) {
|
||||||
[=] { SendToBannedHelp(phone); close(); }));
|
[=] { SendToBannedHelp(phone); close(); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
SentCodeField::SentCodeField(
|
|
||||||
QWidget *parent,
|
|
||||||
const style::InputField &st,
|
|
||||||
rpl::producer<QString> placeholder,
|
|
||||||
const QString &val)
|
|
||||||
: Ui::InputField(parent, st, std::move(placeholder), val) {
|
|
||||||
connect(this, &Ui::InputField::changed, [this] { fix(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void SentCodeField::setAutoSubmit(int length, Fn<void()> submitCallback) {
|
|
||||||
_autoSubmitLength = length;
|
|
||||||
_submitCallback = std::move(submitCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SentCodeField::setChangedCallback(Fn<void()> changedCallback) {
|
|
||||||
_changedCallback = std::move(changedCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SentCodeField::getDigitsOnly() const {
|
|
||||||
return QString(
|
|
||||||
getLastText()
|
|
||||||
).remove(
|
|
||||||
QRegularExpression("[^\\d]")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SentCodeField::fix() {
|
|
||||||
if (_fixing) return;
|
|
||||||
|
|
||||||
_fixing = true;
|
|
||||||
auto newText = QString();
|
|
||||||
const auto now = getLastText();
|
|
||||||
auto oldPos = textCursor().position();
|
|
||||||
auto newPos = -1;
|
|
||||||
auto oldLen = now.size();
|
|
||||||
auto digitCount = 0;
|
|
||||||
for (const auto &ch : now) {
|
|
||||||
if (ch.isDigit()) {
|
|
||||||
++digitCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_autoSubmitLength > 0 && digitCount > _autoSubmitLength) {
|
|
||||||
digitCount = _autoSubmitLength;
|
|
||||||
}
|
|
||||||
auto strict = (_autoSubmitLength > 0)
|
|
||||||
&& (digitCount == _autoSubmitLength);
|
|
||||||
|
|
||||||
newText.reserve(oldLen);
|
|
||||||
int i = 0;
|
|
||||||
for (const auto &ch : now) {
|
|
||||||
if (i++ == oldPos) {
|
|
||||||
newPos = newText.length();
|
|
||||||
}
|
|
||||||
if (ch.isDigit()) {
|
|
||||||
if (!digitCount--) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
newText += ch;
|
|
||||||
if (strict && !digitCount) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (ch == '-') {
|
|
||||||
newText += ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (newPos < 0) {
|
|
||||||
newPos = newText.length();
|
|
||||||
}
|
|
||||||
if (newText != now) {
|
|
||||||
setText(newText);
|
|
||||||
setCursorPosition(newPos);
|
|
||||||
}
|
|
||||||
_fixing = false;
|
|
||||||
|
|
||||||
if (_changedCallback) {
|
|
||||||
_changedCallback();
|
|
||||||
}
|
|
||||||
if (strict && _submitCallback) {
|
|
||||||
_submitCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SentCodeCall::SentCodeCall(
|
|
||||||
FnMut<void()> callCallback,
|
|
||||||
Fn<void()> updateCallback)
|
|
||||||
: _call(std::move(callCallback))
|
|
||||||
, _update(std::move(updateCallback)) {
|
|
||||||
_timer.setCallback([=] {
|
|
||||||
if (_status.state == State::Waiting) {
|
|
||||||
if (--_status.timeout <= 0) {
|
|
||||||
_status.state = State::Calling;
|
|
||||||
_timer.cancel();
|
|
||||||
if (_call) {
|
|
||||||
_call();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_update) {
|
|
||||||
_update();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void SentCodeCall::setStatus(const Status &status) {
|
|
||||||
_status = status;
|
|
||||||
if (_status.state == State::Waiting) {
|
|
||||||
_timer.callEach(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SentCodeCall::getText() const {
|
|
||||||
switch (_status.state) {
|
|
||||||
case State::Waiting: {
|
|
||||||
if (_status.timeout >= 3600) {
|
|
||||||
return tr::lng_code_call(tr::now, lt_minutes, qsl("%1:%2").arg(_status.timeout / 3600).arg((_status.timeout / 60) % 60, 2, 10, QChar('0')), lt_seconds, qsl("%1").arg(_status.timeout % 60, 2, 10, QChar('0')));
|
|
||||||
}
|
|
||||||
return tr::lng_code_call(tr::now, lt_minutes, QString::number(_status.timeout / 60), lt_seconds, qsl("%1").arg(_status.timeout % 60, 2, 10, QChar('0')));
|
|
||||||
} break;
|
|
||||||
case State::Calling: return tr::lng_code_calling(tr::now);
|
|
||||||
case State::Called: return tr::lng_code_called(tr::now);
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfirmPhoneBox::Start(
|
void ConfirmPhoneBox::Start(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const QString &phone,
|
const QString &phone,
|
||||||
|
@ -262,7 +137,7 @@ void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) {
|
||||||
_phoneHash = qs(data.vphone_code_hash());
|
_phoneHash = qs(data.vphone_code_hash());
|
||||||
if (const auto nextType = data.vnext_type()) {
|
if (const auto nextType = data.vnext_type()) {
|
||||||
if (nextType->type() == mtpc_auth_codeTypeCall) {
|
if (nextType->type() == mtpc_auth_codeTypeCall) {
|
||||||
_call.setStatus({ SentCodeCall::State::Waiting, data.vtimeout().value_or(60) });
|
_call.setStatus({ Ui::SentCodeCall::State::Waiting, data.vtimeout().value_or(60) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
launch();
|
launch();
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/widgets/sent_code_field.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -23,72 +24,6 @@ class Session;
|
||||||
|
|
||||||
void ShowPhoneBannedError(const QString &phone);
|
void ShowPhoneBannedError(const QString &phone);
|
||||||
|
|
||||||
class SentCodeField : public Ui::InputField {
|
|
||||||
public:
|
|
||||||
SentCodeField(
|
|
||||||
QWidget *parent,
|
|
||||||
const style::InputField &st,
|
|
||||||
rpl::producer<QString> placeholder = nullptr,
|
|
||||||
const QString &val = QString());
|
|
||||||
|
|
||||||
void setAutoSubmit(int length, Fn<void()> submitCallback);
|
|
||||||
void setChangedCallback(Fn<void()> changedCallback);
|
|
||||||
QString getDigitsOnly() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void fix();
|
|
||||||
|
|
||||||
// Flag for not calling onTextChanged() recursively.
|
|
||||||
bool _fixing = false;
|
|
||||||
|
|
||||||
int _autoSubmitLength = 0;
|
|
||||||
Fn<void()> _submitCallback;
|
|
||||||
Fn<void()> _changedCallback;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class SentCodeCall {
|
|
||||||
public:
|
|
||||||
SentCodeCall(
|
|
||||||
FnMut<void()> callCallback,
|
|
||||||
Fn<void()> updateCallback);
|
|
||||||
|
|
||||||
enum class State {
|
|
||||||
Waiting,
|
|
||||||
Calling,
|
|
||||||
Called,
|
|
||||||
Disabled,
|
|
||||||
};
|
|
||||||
struct Status {
|
|
||||||
Status() {
|
|
||||||
}
|
|
||||||
Status(State state, int timeout) : state(state), timeout(timeout) {
|
|
||||||
}
|
|
||||||
|
|
||||||
State state = State::Disabled;
|
|
||||||
int timeout = 0;
|
|
||||||
};
|
|
||||||
void setStatus(const Status &status);
|
|
||||||
|
|
||||||
void callDone() {
|
|
||||||
if (_status.state == State::Calling) {
|
|
||||||
_status.state = State::Called;
|
|
||||||
if (_update) {
|
|
||||||
_update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getText() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Status _status;
|
|
||||||
base::Timer _timer;
|
|
||||||
FnMut<void()> _call;
|
|
||||||
Fn<void()> _update;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConfirmPhoneBox final : public Ui::BoxContent {
|
class ConfirmPhoneBox final : public Ui::BoxContent {
|
||||||
public:
|
public:
|
||||||
static void Start(
|
static void Start(
|
||||||
|
@ -149,9 +84,9 @@ private:
|
||||||
mtpRequestId _checkCodeRequestId = 0;
|
mtpRequestId _checkCodeRequestId = 0;
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> _about = { nullptr };
|
object_ptr<Ui::FlatLabel> _about = { nullptr };
|
||||||
object_ptr<SentCodeField> _code = { nullptr };
|
object_ptr<Ui::SentCodeField> _code = { nullptr };
|
||||||
|
|
||||||
QString _error;
|
QString _error;
|
||||||
SentCodeCall _call;
|
Ui::SentCodeCall _call;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/bytes.h"
|
#include "base/bytes.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "boxes/confirm_phone_box.h"
|
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -24,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/widgets/sent_code_field.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
#include "passport/passport_encryption.h"
|
#include "passport/passport_encryption.h"
|
||||||
|
|
|
@ -79,7 +79,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/qthelp_regex.h"
|
#include "base/qthelp_regex.h"
|
||||||
#include "base/qthelp_url.h"
|
#include "base/qthelp_url.h"
|
||||||
#include "boxes/connection_box.h"
|
#include "boxes/connection_box.h"
|
||||||
#include "boxes/confirm_phone_box.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
|
|
@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
#include "ui/widgets/sent_code_field.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
@ -2181,11 +2182,11 @@ void FormController::startPhoneVerification(not_null<Value*> value) {
|
||||||
value->verification.codeLength = (type.vlength().v > 0)
|
value->verification.codeLength = (type.vlength().v > 0)
|
||||||
? type.vlength().v
|
? type.vlength().v
|
||||||
: -1;
|
: -1;
|
||||||
value->verification.call = std::make_unique<SentCodeCall>(
|
value->verification.call = std::make_unique<Ui::SentCodeCall>(
|
||||||
[=] { requestPhoneCall(value); },
|
[=] { requestPhoneCall(value); },
|
||||||
[=] { _verificationUpdate.fire_copy(value); });
|
[=] { _verificationUpdate.fire_copy(value); });
|
||||||
value->verification.call->setStatus(
|
value->verification.call->setStatus(
|
||||||
{ SentCodeCall::State::Called, 0 });
|
{ Ui::SentCodeCall::State::Called, 0 });
|
||||||
if (data.vnext_type()) {
|
if (data.vnext_type()) {
|
||||||
LOG(("API Error: next_type is not supported for calls."));
|
LOG(("API Error: next_type is not supported for calls."));
|
||||||
}
|
}
|
||||||
|
@ -2197,11 +2198,11 @@ void FormController::startPhoneVerification(not_null<Value*> value) {
|
||||||
: -1;
|
: -1;
|
||||||
const auto next = data.vnext_type();
|
const auto next = data.vnext_type();
|
||||||
if (next && next->type() == mtpc_auth_codeTypeCall) {
|
if (next && next->type() == mtpc_auth_codeTypeCall) {
|
||||||
value->verification.call = std::make_unique<SentCodeCall>(
|
value->verification.call = std::make_unique<Ui::SentCodeCall>(
|
||||||
[=] { requestPhoneCall(value); },
|
[=] { requestPhoneCall(value); },
|
||||||
[=] { _verificationUpdate.fire_copy(value); });
|
[=] { _verificationUpdate.fire_copy(value); });
|
||||||
value->verification.call->setStatus({
|
value->verification.call->setStatus({
|
||||||
SentCodeCall::State::Waiting,
|
Ui::SentCodeCall::State::Waiting,
|
||||||
data.vtimeout().value_or(60) });
|
data.vtimeout().value_or(60) });
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -2235,7 +2236,7 @@ void FormController::requestPhoneCall(not_null<Value*> value) {
|
||||||
Expects(value->verification.call != nullptr);
|
Expects(value->verification.call != nullptr);
|
||||||
|
|
||||||
value->verification.call->setStatus(
|
value->verification.call->setStatus(
|
||||||
{ SentCodeCall::State::Calling, 0 });
|
{ Ui::SentCodeCall::State::Calling, 0 });
|
||||||
_api.request(MTPauth_ResendCode(
|
_api.request(MTPauth_ResendCode(
|
||||||
MTP_string(getPhoneFromValue(value)),
|
MTP_string(getPhoneFromValue(value)),
|
||||||
MTP_string(value->verification.phoneCodeHash)
|
MTP_string(value->verification.phoneCodeHash)
|
||||||
|
|
|
@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "boxes/confirm_phone_box.h"
|
#include "base/timer.h"
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
#include "core/core_cloud_password.h"
|
#include "core/core_cloud_password.h"
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class SentCodeCall;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Passport {
|
namespace Passport {
|
||||||
|
|
||||||
struct EditDocumentCountry;
|
struct EditDocumentCountry;
|
||||||
|
@ -184,7 +188,7 @@ struct Verification {
|
||||||
mtpRequestId requestId = 0;
|
mtpRequestId requestId = 0;
|
||||||
QString phoneCodeHash;
|
QString phoneCodeHash;
|
||||||
int codeLength = 0;
|
int codeLength = 0;
|
||||||
std::unique_ptr<SentCodeCall> call;
|
std::unique_ptr<Ui::SentCodeCall> call;
|
||||||
|
|
||||||
QString error;
|
QString error;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "passport/passport_form_controller.h"
|
#include "passport/passport_form_controller.h"
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
|
#include "ui/layers/box_content.h"
|
||||||
|
|
||||||
namespace Passport {
|
namespace Passport {
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/countryinput.h"
|
#include "ui/countryinput.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/widgets/sent_code_field.h"
|
||||||
#include "core/update_checker.h"
|
#include "core/update_checker.h"
|
||||||
#include "countries/countries_instance.h"
|
#include "countries/countries_instance.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/widgets/box_content_divider.h"
|
#include "ui/widgets/box_content_divider.h"
|
||||||
|
#include "ui/widgets/sent_code_field.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
|
@ -61,7 +62,7 @@ private:
|
||||||
|
|
||||||
rpl::producer<QString> _title;
|
rpl::producer<QString> _title;
|
||||||
Fn<void()> _submit;
|
Fn<void()> _submit;
|
||||||
QPointer<SentCodeField> _code;
|
QPointer<Ui::SentCodeField> _code;
|
||||||
QPointer<Ui::VerticalLayout> _content;
|
QPointer<Ui::VerticalLayout> _content;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -109,7 +110,7 @@ void VerifyBox::setupControls(
|
||||||
st::boxLabel),
|
st::boxLabel),
|
||||||
small);
|
small);
|
||||||
_code = _content->add(
|
_code = _content->add(
|
||||||
object_ptr<SentCodeField>(
|
object_ptr<Ui::SentCodeField>(
|
||||||
_content,
|
_content,
|
||||||
st::defaultInputField,
|
st::defaultInputField,
|
||||||
tr::lng_change_phone_code_title()),
|
tr::lng_change_phone_code_title()),
|
||||||
|
@ -177,9 +178,9 @@ void VerifyBox::setupControls(
|
||||||
if (codeLength > 0) {
|
if (codeLength > 0) {
|
||||||
_code->setAutoSubmit(codeLength, _submit);
|
_code->setAutoSubmit(codeLength, _submit);
|
||||||
} else {
|
} else {
|
||||||
connect(_code, &SentCodeField::submitted, _submit);
|
connect(_code, &Ui::SentCodeField::submitted, _submit);
|
||||||
}
|
}
|
||||||
connect(_code, &SentCodeField::changed, [=] {
|
connect(_code, &Ui::SentCodeField::changed, [=] {
|
||||||
problem->hide(anim::type::normal);
|
problem->hide(anim::type::normal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
162
Telegram/SourceFiles/ui/widgets/sent_code_field.cpp
Normal file
162
Telegram/SourceFiles/ui/widgets/sent_code_field.cpp
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
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 "ui/widgets/sent_code_field.h"
|
||||||
|
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
SentCodeField::SentCodeField(
|
||||||
|
QWidget *parent,
|
||||||
|
const style::InputField &st,
|
||||||
|
rpl::producer<QString> placeholder,
|
||||||
|
const QString &val)
|
||||||
|
: Ui::InputField(parent, st, std::move(placeholder), val) {
|
||||||
|
connect(this, &Ui::InputField::changed, [this] { fix(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SentCodeField::setAutoSubmit(int length, Fn<void()> submitCallback) {
|
||||||
|
_autoSubmitLength = length;
|
||||||
|
_submitCallback = std::move(submitCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SentCodeField::setChangedCallback(Fn<void()> changedCallback) {
|
||||||
|
_changedCallback = std::move(changedCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SentCodeField::getDigitsOnly() const {
|
||||||
|
return QString(
|
||||||
|
getLastText()
|
||||||
|
).remove(
|
||||||
|
QRegularExpression("[^\\d]")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SentCodeField::fix() {
|
||||||
|
if (_fixing) return;
|
||||||
|
|
||||||
|
_fixing = true;
|
||||||
|
auto newText = QString();
|
||||||
|
const auto now = getLastText();
|
||||||
|
auto oldPos = textCursor().position();
|
||||||
|
auto newPos = -1;
|
||||||
|
auto oldLen = now.size();
|
||||||
|
auto digitCount = 0;
|
||||||
|
for (const auto &ch : now) {
|
||||||
|
if (ch.isDigit()) {
|
||||||
|
++digitCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_autoSubmitLength > 0 && digitCount > _autoSubmitLength) {
|
||||||
|
digitCount = _autoSubmitLength;
|
||||||
|
}
|
||||||
|
const auto strict = (_autoSubmitLength > 0)
|
||||||
|
&& (digitCount == _autoSubmitLength);
|
||||||
|
|
||||||
|
newText.reserve(oldLen);
|
||||||
|
int i = 0;
|
||||||
|
for (const auto &ch : now) {
|
||||||
|
if (i++ == oldPos) {
|
||||||
|
newPos = newText.length();
|
||||||
|
}
|
||||||
|
if (ch.isDigit()) {
|
||||||
|
if (!digitCount--) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newText += ch;
|
||||||
|
if (strict && !digitCount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (ch == '-') {
|
||||||
|
newText += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newPos < 0) {
|
||||||
|
newPos = newText.length();
|
||||||
|
}
|
||||||
|
if (newText != now) {
|
||||||
|
setText(newText);
|
||||||
|
setCursorPosition(newPos);
|
||||||
|
}
|
||||||
|
_fixing = false;
|
||||||
|
|
||||||
|
if (_changedCallback) {
|
||||||
|
_changedCallback();
|
||||||
|
}
|
||||||
|
if (strict && _submitCallback) {
|
||||||
|
_submitCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SentCodeCall::SentCodeCall(
|
||||||
|
FnMut<void()> callCallback,
|
||||||
|
Fn<void()> updateCallback)
|
||||||
|
: _call(std::move(callCallback))
|
||||||
|
, _update(std::move(updateCallback)) {
|
||||||
|
_timer.setCallback([=] {
|
||||||
|
if (_status.state == State::Waiting) {
|
||||||
|
if (--_status.timeout <= 0) {
|
||||||
|
_status.state = State::Calling;
|
||||||
|
_timer.cancel();
|
||||||
|
if (_call) {
|
||||||
|
_call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_update) {
|
||||||
|
_update();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SentCodeCall::setStatus(const Status &status) {
|
||||||
|
_status = status;
|
||||||
|
if (_status.state == State::Waiting) {
|
||||||
|
_timer.callEach(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SentCodeCall::getText() const {
|
||||||
|
switch (_status.state) {
|
||||||
|
case State::Waiting: {
|
||||||
|
if (_status.timeout >= 3600) {
|
||||||
|
return tr::lng_code_call(
|
||||||
|
tr::now,
|
||||||
|
lt_minutes,
|
||||||
|
(u"%1:%2"_q)
|
||||||
|
.arg(_status.timeout / 3600)
|
||||||
|
.arg((_status.timeout / 60) % 60, 2, 10, QChar('0')),
|
||||||
|
lt_seconds,
|
||||||
|
(u"%1"_q).arg(_status.timeout % 60, 2, 10, QChar('0')));
|
||||||
|
}
|
||||||
|
return tr::lng_code_call(
|
||||||
|
tr::now,
|
||||||
|
lt_minutes,
|
||||||
|
QString::number(_status.timeout / 60),
|
||||||
|
lt_seconds,
|
||||||
|
(u"%1"_q).arg(_status.timeout % 60, 2, 10, QChar('0')));
|
||||||
|
} break;
|
||||||
|
case State::Calling: return tr::lng_code_calling(tr::now);
|
||||||
|
case State::Called: return tr::lng_code_called(tr::now);
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SentCodeCall::callDone() {
|
||||||
|
if (_status.state == State::Calling) {
|
||||||
|
_status.state = State::Called;
|
||||||
|
if (_update) {
|
||||||
|
_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ui
|
74
Telegram/SourceFiles/ui/widgets/sent_code_field.h
Normal file
74
Telegram/SourceFiles/ui/widgets/sent_code_field.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
class SentCodeField final : public Ui::InputField {
|
||||||
|
public:
|
||||||
|
SentCodeField(
|
||||||
|
QWidget *parent,
|
||||||
|
const style::InputField &st,
|
||||||
|
rpl::producer<QString> placeholder = nullptr,
|
||||||
|
const QString &val = QString());
|
||||||
|
|
||||||
|
void setAutoSubmit(int length, Fn<void()> submitCallback);
|
||||||
|
void setChangedCallback(Fn<void()> changedCallback);
|
||||||
|
[[nodiscard]] QString getDigitsOnly() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void fix();
|
||||||
|
|
||||||
|
// Flag for not calling onTextChanged() recursively.
|
||||||
|
bool _fixing = false;
|
||||||
|
|
||||||
|
int _autoSubmitLength = 0;
|
||||||
|
Fn<void()> _submitCallback;
|
||||||
|
Fn<void()> _changedCallback;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SentCodeCall final {
|
||||||
|
public:
|
||||||
|
SentCodeCall(
|
||||||
|
FnMut<void()> callCallback,
|
||||||
|
Fn<void()> updateCallback);
|
||||||
|
|
||||||
|
enum class State {
|
||||||
|
Waiting,
|
||||||
|
Calling,
|
||||||
|
Called,
|
||||||
|
Disabled,
|
||||||
|
};
|
||||||
|
struct Status {
|
||||||
|
Status() {
|
||||||
|
}
|
||||||
|
Status(State state, int timeout) : state(state), timeout(timeout) {
|
||||||
|
}
|
||||||
|
|
||||||
|
State state = State::Disabled;
|
||||||
|
int timeout = 0;
|
||||||
|
};
|
||||||
|
void setStatus(const Status &status);
|
||||||
|
|
||||||
|
void callDone();
|
||||||
|
|
||||||
|
[[nodiscard]] QString getText() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Status _status;
|
||||||
|
base::Timer _timer;
|
||||||
|
FnMut<void()> _call;
|
||||||
|
Fn<void()> _update;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -177,8 +177,12 @@ PRIVATE
|
||||||
ui/text/text_options.h
|
ui/text/text_options.h
|
||||||
ui/toasts/common_toasts.cpp
|
ui/toasts/common_toasts.cpp
|
||||||
ui/toasts/common_toasts.h
|
ui/toasts/common_toasts.h
|
||||||
|
|
||||||
|
ui/widgets/sent_code_field.cpp
|
||||||
|
ui/widgets/sent_code_field.h
|
||||||
ui/widgets/separate_panel.cpp
|
ui/widgets/separate_panel.cpp
|
||||||
ui/widgets/separate_panel.h
|
ui/widgets/separate_panel.h
|
||||||
|
|
||||||
ui/cached_round_corners.cpp
|
ui/cached_round_corners.cpp
|
||||||
ui/cached_round_corners.h
|
ui/cached_round_corners.h
|
||||||
ui/grouped_layout.cpp
|
ui/grouped_layout.cpp
|
||||||
|
|
Loading…
Add table
Reference in a new issue