Added support of multiple phone pattern groups.

This commit is contained in:
23rd 2022-12-28 18:09:03 +03:00
parent be8aeb0d96
commit 8748265b00
3 changed files with 75 additions and 26 deletions

View File

@ -356,24 +356,55 @@ FormatResult CountriesInstance::format(FormatArgs args) {
const auto codeSize = int(bestCallingCodePtr->callingCode.size());
if (args.onlyGroups && args.incomplete) {
auto groups = args.skipCode
auto initialGroups = args.skipCode
? QVector<int>()
: QVector<int>{ codeSize };
auto groupSize = 0;
auto initialGroupsSize = 0;
if (bestCallingCodePtr->patterns.empty()) {
return FormatResult{ .groups = std::move(groups) };
return FormatResult{ .groups = std::move(initialGroups) };
}
for (const auto &c : bestCallingCodePtr->patterns.front()) {
if (c == ' ') {
groups.push_back(base::take(groupSize));
} else {
groupSize++;
auto bestGroups = initialGroups;
auto bestGroupsSize = initialGroupsSize;
auto bestPatternMaxMatches = -1;
for (const auto &pattern : bestCallingCodePtr->patterns) {
auto groups = initialGroups;
auto groupSize = initialGroupsSize;
auto lastSpacesCount = 0;
auto maxMatchedDigits = 0;
auto isNotBestPattern = false;
for (auto i = 0; i < pattern.size(); i++) {
const auto c = pattern.at(i);
if (c.isDigit()) {
const auto n = (i - lastSpacesCount) + codeSize;
if (n < phoneNumber.size()) {
if (phoneNumber.at(n) == c) {
maxMatchedDigits++;
} else {
isNotBestPattern = true;
}
} else {
isNotBestPattern = true;
}
}
if (c.isSpace()) {
groups.push_back(base::take(groupSize));
lastSpacesCount++;
} else {
groupSize++;
}
}
if (maxMatchedDigits > bestPatternMaxMatches) {
bestPatternMaxMatches = isNotBestPattern
? -1
: maxMatchedDigits;
bestGroups = std::move(groups);
bestGroupsSize = groupSize;
}
}
if (groupSize) {
groups.push_back(base::take(groupSize));
if (bestGroupsSize) {
bestGroups.push_back(base::take(bestGroupsSize));
}
return FormatResult{ .groups = std::move(groups) };
return FormatResult{ .groups = std::move(bestGroups) };
}
const auto formattedPart = phoneNumber.mid(codeSize);

View File

@ -134,6 +134,12 @@ void PhonePartInput::correctValue(
int wasCursor,
QString &now,
int &nowCursor) {
if (!now.isEmpty() && (_lastDigits != now)) {
_lastDigits = now;
_lastDigits.replace(QRegularExpression("[^\\d]"), QString());
updatePattern(_groupsCallback(_code + _lastDigits));
}
QString newText;
int oldPos(nowCursor), newPos(-1), oldLen(now.length()), digitCount = 0;
for (int i = 0; i < oldLen; ++i) {
@ -212,21 +218,8 @@ void PhonePartInput::addedToNumber(const QString &added) {
}
void PhonePartInput::chooseCode(const QString &code) {
_pattern = _groupsCallback(code);
if (!_pattern.isEmpty() && _pattern.at(0) == code.size()) {
_pattern.pop_front();
} else {
_pattern.clear();
}
_additionalPlaceholder = QString();
if (!_pattern.isEmpty()) {
_additionalPlaceholder.reserve(20);
for (const auto part : std::as_const(_pattern)) {
_additionalPlaceholder.append(' ');
_additionalPlaceholder.append(QString(part, QChar(0x2212)));
}
}
setPlaceholderHidden(!_additionalPlaceholder.isEmpty());
_code = code;
updatePattern(_groupsCallback(_code));
auto wasText = getLastText();
auto wasCursor = cursorPosition();
@ -239,6 +232,27 @@ void PhonePartInput::chooseCode(const QString &code) {
update();
}
void PhonePartInput::updatePattern(QVector<int> &&pattern) {
if (_pattern == pattern) {
return;
}
_pattern = std::move(pattern);
if (!_pattern.isEmpty() && _pattern.at(0) == _code.size()) {
_pattern.pop_front();
} else {
_pattern.clear();
}
_additionalPlaceholder = QString();
if (!_pattern.isEmpty()) {
_additionalPlaceholder.reserve(20);
for (const auto &part : _pattern) {
_additionalPlaceholder.append(' ');
_additionalPlaceholder.append(QString(part, QChar(0x2212)));
}
}
setPlaceholderHidden(!_additionalPlaceholder.isEmpty());
}
UsernameInput::UsernameInput(
QWidget *parent,
const style::InputField &st,

View File

@ -68,6 +68,10 @@ protected:
void paintAdditionalPlaceholder(QPainter &p) override;
private:
void updatePattern(QVector<int> &&pattern);
QString _code;
QString _lastDigits;
QVector<int> _pattern;
QString _additionalPlaceholder;
rpl::event_stream<not_null<QKeyEvent*>> _frontBackspaceEvent;