| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- /*
- 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) {
- changes() | rpl::start_with_next([=] { fix(); }, lifetime());
- }
- 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(TextUtilities::RegExpDigitsExclude());
- }
- 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
|