mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added all available calling codes on each country to CountrySelectBox.
This commit is contained in:
parent
45360adbc2
commit
48f7d715d6
4 changed files with 86 additions and 26 deletions
|
@ -40,7 +40,7 @@ public:
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> countryChosen() const {
|
[[nodiscard]] rpl::producer<Entry> countryChosen() const {
|
||||||
return _countryChosen.events();
|
return _countryChosen.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ private:
|
||||||
void updateSelectedRow();
|
void updateSelectedRow();
|
||||||
void updateRow(int index);
|
void updateRow(int index);
|
||||||
void setPressed(int pressed);
|
void setPressed(int pressed);
|
||||||
const std::vector<not_null<const Countries::Info*>> ¤t() const;
|
const std::vector<Entry> ¤t() const;
|
||||||
|
|
||||||
Type _type = Type::Phones;
|
Type _type = Type::Phones;
|
||||||
int _rowHeight = 0;
|
int _rowHeight = 0;
|
||||||
|
@ -76,12 +76,12 @@ private:
|
||||||
|
|
||||||
std::vector<std::unique_ptr<RippleAnimation>> _ripples;
|
std::vector<std::unique_ptr<RippleAnimation>> _ripples;
|
||||||
|
|
||||||
std::vector<not_null<const Countries::Info*>> _list;
|
std::vector<Entry> _list;
|
||||||
std::vector<not_null<const Countries::Info*>> _filtered;
|
std::vector<Entry> _filtered;
|
||||||
base::flat_map<QChar, std::vector<int>> _byLetter;
|
base::flat_map<QChar, std::vector<int>> _byLetter;
|
||||||
std::vector<std::vector<QString>> _namesList;
|
std::vector<std::vector<QString>> _namesList;
|
||||||
|
|
||||||
rpl::event_stream<QString> _countryChosen;
|
rpl::event_stream<Entry> _countryChosen;
|
||||||
rpl::event_stream<ScrollToRequest> _mustScrollTo;
|
rpl::event_stream<ScrollToRequest> _mustScrollTo;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -98,6 +98,16 @@ CountrySelectBox::CountrySelectBox(QWidget*, const QString &iso, Type type)
|
||||||
rpl::producer<QString> CountrySelectBox::countryChosen() const {
|
rpl::producer<QString> CountrySelectBox::countryChosen() const {
|
||||||
Expects(_ownedInner != nullptr || _inner != nullptr);
|
Expects(_ownedInner != nullptr || _inner != nullptr);
|
||||||
|
|
||||||
|
return (_ownedInner
|
||||||
|
? _ownedInner.data()
|
||||||
|
: _inner.data())->countryChosen() | rpl::map([](const Entry &e) {
|
||||||
|
return e.iso2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<CountrySelectBox::Entry> CountrySelectBox::entryChosen() const {
|
||||||
|
Expects(_ownedInner != nullptr || _inner != nullptr);
|
||||||
|
|
||||||
return (_ownedInner
|
return (_ownedInner
|
||||||
? _ownedInner.data()
|
? _ownedInner.data()
|
||||||
: _inner.data())->countryChosen();
|
: _inner.data())->countryChosen();
|
||||||
|
@ -180,25 +190,36 @@ CountrySelectBox::Inner::Inner(
|
||||||
LastValidISO = iso;
|
LastValidISO = iso;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto extractEntries = [&](const Countries::Info &info) {
|
||||||
|
for (const auto &code : info.codes) {
|
||||||
|
_list.push_back(Entry{
|
||||||
|
.country = info.name,
|
||||||
|
.iso2 = info.iso2,
|
||||||
|
.code = code.callingCode,
|
||||||
|
.alternativeName = info.alternativeName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
_list.reserve(byISO2.size());
|
_list.reserve(byISO2.size());
|
||||||
_namesList.reserve(byISO2.size());
|
_namesList.reserve(byISO2.size());
|
||||||
|
|
||||||
const auto l = byISO2.constFind(LastValidISO);
|
const auto l = byISO2.constFind(LastValidISO);
|
||||||
const auto lastValid = (l != byISO2.cend()) ? (*l) : nullptr;
|
const auto lastValid = (l != byISO2.cend()) ? (*l) : nullptr;
|
||||||
if (lastValid) {
|
if (lastValid) {
|
||||||
_list.emplace_back(lastValid);
|
extractEntries(*lastValid);
|
||||||
}
|
}
|
||||||
for (const auto &entry : Countries::Instance().list()) {
|
for (const auto &entry : Countries::Instance().list()) {
|
||||||
if (&entry != lastValid) {
|
if (&entry != lastValid) {
|
||||||
_list.emplace_back(&entry);
|
extractEntries(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
for (const auto info : _list) {
|
for (const auto info : _list) {
|
||||||
auto full = info->name
|
auto full = info.country
|
||||||
+ ' '
|
+ ' '
|
||||||
+ (!info->alternativeName.isEmpty()
|
+ (!info.alternativeName.isEmpty()
|
||||||
? info->alternativeName
|
? info.alternativeName
|
||||||
: QString());
|
: QString());
|
||||||
const auto namesList = std::move(full).toLower().split(
|
const auto namesList = std::move(full).toLower().split(
|
||||||
QRegularExpression("[\\s\\-]"),
|
QRegularExpression("[\\s\\-]"),
|
||||||
|
@ -256,10 +277,10 @@ void CountrySelectBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto code = QString("+") + list[i]->codes.front().callingCode;
|
auto code = QString("+") + list[i].code;
|
||||||
auto codeWidth = st::countryRowCodeFont->width(code);
|
auto codeWidth = st::countryRowCodeFont->width(code);
|
||||||
|
|
||||||
auto name = list[i]->name;
|
auto name = list[i].country;
|
||||||
auto nameWidth = st::countryRowNameFont->width(name);
|
auto nameWidth = st::countryRowNameFont->width(name);
|
||||||
auto availWidth = width() - st::countryRowPadding.left() - st::countryRowPadding.right() - codeWidth - st::boxScroll.width;
|
auto availWidth = width() - st::countryRowPadding.left() - st::countryRowPadding.right() - codeWidth - st::boxScroll.width;
|
||||||
if (nameWidth > availWidth) {
|
if (nameWidth > availWidth) {
|
||||||
|
@ -399,9 +420,9 @@ void CountrySelectBox::Inner::selectSkipPage(int32 h, int32 dir) {
|
||||||
|
|
||||||
void CountrySelectBox::Inner::chooseCountry() {
|
void CountrySelectBox::Inner::chooseCountry() {
|
||||||
const auto &list = current();
|
const auto &list = current();
|
||||||
_countryChosen.fire((_selected >= 0 && _selected < list.size())
|
_countryChosen.fire_copy((_selected >= 0 && _selected < list.size())
|
||||||
? QString(list[_selected]->iso2)
|
? list[_selected]
|
||||||
: QString());
|
: Entry());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::refresh() {
|
void CountrySelectBox::Inner::refresh() {
|
||||||
|
@ -424,7 +445,7 @@ void CountrySelectBox::Inner::updateSelected(QPoint localPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CountrySelectBox::Inner::current() const
|
auto CountrySelectBox::Inner::current() const
|
||||||
-> const std::vector<not_null<const Countries::Info*>> & {
|
-> const std::vector<CountrySelectBox::Entry> & {
|
||||||
return _filter.isEmpty() ? _list : _filtered;
|
return _filter.isEmpty() ? _list : _filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,18 @@ public:
|
||||||
Phones,
|
Phones,
|
||||||
Countries,
|
Countries,
|
||||||
};
|
};
|
||||||
|
struct Entry {
|
||||||
|
QString country;
|
||||||
|
QString iso2;
|
||||||
|
QString code;
|
||||||
|
QString alternativeName;
|
||||||
|
};
|
||||||
|
|
||||||
CountrySelectBox(QWidget*);
|
CountrySelectBox(QWidget*);
|
||||||
CountrySelectBox(QWidget*, const QString &iso, Type type);
|
CountrySelectBox(QWidget*, const QString &iso, Type type);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> countryChosen() const;
|
[[nodiscard]] rpl::producer<QString> countryChosen() const;
|
||||||
|
[[nodiscard]] rpl::producer<Entry> entryChosen() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
|
|
@ -92,10 +92,33 @@ void CountryInput::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void CountryInput::mousePressEvent(QMouseEvent *e) {
|
void CountryInput::mousePressEvent(QMouseEvent *e) {
|
||||||
mouseMoveEvent(e);
|
mouseMoveEvent(e);
|
||||||
if (_active) {
|
if (_active) {
|
||||||
auto box = Ui::show(Box<Ui::CountrySelectBox>());
|
const auto box = Ui::show(Box<Ui::CountrySelectBox>());
|
||||||
box->countryChosen(
|
box->entryChosen(
|
||||||
) | rpl::start_with_next([=](QString iso) {
|
) | rpl::start_with_next([=](
|
||||||
chooseCountry(iso);
|
const Ui::CountrySelectBox::Entry &entry) {
|
||||||
|
if (box) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &list = Countries::Instance().list();
|
||||||
|
auto index = 0;
|
||||||
|
const auto infoIt = ranges::find(
|
||||||
|
list,
|
||||||
|
entry.iso2,
|
||||||
|
&Countries::Info::iso2);
|
||||||
|
if (infoIt == end(list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto info = *infoIt;
|
||||||
|
const auto it = ranges::find(
|
||||||
|
info.codes,
|
||||||
|
entry.code,
|
||||||
|
&Countries::CallingCodeInfo::callingCode);
|
||||||
|
if (it != end(info.codes)) {
|
||||||
|
chooseCountry(
|
||||||
|
&info,
|
||||||
|
std::distance(begin(info.codes), it));
|
||||||
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,23 +153,27 @@ void CountryInput::onChooseCode(const QString &code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CountryInput::chooseCountry(const QString &iso) {
|
bool CountryInput::chooseCountry(const QString &iso) {
|
||||||
Ui::hideLayer();
|
|
||||||
|
|
||||||
const auto &byISO2 = Countries::Instance().byISO2();
|
const auto &byISO2 = Countries::Instance().byISO2();
|
||||||
const auto i = byISO2.constFind(iso);
|
const auto i = byISO2.constFind(iso);
|
||||||
const auto info = (i != byISO2.cend()) ? (*i) : nullptr;
|
const auto info = (i != byISO2.cend()) ? (*i) : nullptr;
|
||||||
|
|
||||||
_chosenIso = QString();
|
_chosenIso = QString();
|
||||||
if (info) {
|
if (info) {
|
||||||
_chosenIso = LastValidISO = info->iso2;
|
chooseCountry(info, 0);
|
||||||
setText(info->name);
|
|
||||||
codeChanged(info->codes.front().callingCode);
|
|
||||||
update();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CountryInput::chooseCountry(
|
||||||
|
not_null<const Countries::Info*> info,
|
||||||
|
int codeIndex) {
|
||||||
|
_chosenIso = LastValidISO = info->iso2;
|
||||||
|
setText(info->name);
|
||||||
|
codeChanged(info->codes[codeIndex].callingCode);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void CountryInput::setText(const QString &newText) {
|
void CountryInput::setText(const QString &newText) {
|
||||||
_text = _st.font->elided(newText, width() - _st.textMargins.left() - _st.textMargins.right());
|
_text = _st.font->elided(newText, width() - _st.textMargins.left() - _st.textMargins.right());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@ namespace Data {
|
||||||
struct Info;
|
struct Info;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Countries {
|
||||||
|
struct Info;
|
||||||
|
} // namespace Countries
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MultiSelect;
|
class MultiSelect;
|
||||||
class RippleAnimation;
|
class RippleAnimation;
|
||||||
|
@ -44,6 +48,7 @@ protected:
|
||||||
void leaveEventHook(QEvent *e) override;
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void chooseCountry(not_null<const Countries::Info*> info, int codeIndex);
|
||||||
void setText(const QString &newText);
|
void setText(const QString &newText);
|
||||||
|
|
||||||
const style::InputField &_st;
|
const style::InputField &_st;
|
||||||
|
|
Loading…
Add table
Reference in a new issue