mirror of https://github.com/procxx/kepka.git
Fix crash in emoji keywords init.
This commit is contained in:
parent
dba677dcc7
commit
817e9aa43d
|
@ -20,6 +20,7 @@ namespace ChatHelpers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kRefreshEach = 60 * 60 * crl::time(1000); // 1 hour.
|
constexpr auto kRefreshEach = 60 * 60 * crl::time(1000); // 1 hour.
|
||||||
|
constexpr auto kKeepNotUsedLangPacksCount = 10;
|
||||||
|
|
||||||
using namespace Ui::Emoji;
|
using namespace Ui::Emoji;
|
||||||
|
|
||||||
|
@ -208,6 +209,8 @@ public:
|
||||||
LangPack &operator=(const LangPack &other) = delete;
|
LangPack &operator=(const LangPack &other) = delete;
|
||||||
~LangPack();
|
~LangPack();
|
||||||
|
|
||||||
|
[[nodiscard]] QString id() const;
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
void apiChanged();
|
void apiChanged();
|
||||||
|
|
||||||
|
@ -270,6 +273,10 @@ void EmojiKeywords::LangPack::readLocalCache() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString EmojiKeywords::LangPack::id() const {
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiKeywords::LangPack::refresh() {
|
void EmojiKeywords::LangPack::refresh() {
|
||||||
if (_state != State::Refreshed) {
|
if (_state != State::Refreshed) {
|
||||||
return;
|
return;
|
||||||
|
@ -417,6 +424,7 @@ void EmojiKeywords::handleAuthSessionChanges() {
|
||||||
void EmojiKeywords::apiChanged(ApiWrap *api) {
|
void EmojiKeywords::apiChanged(ApiWrap *api) {
|
||||||
_api = api;
|
_api = api;
|
||||||
if (_api) {
|
if (_api) {
|
||||||
|
crl::on_main(&Auth(), crl::guard(&_guard, [=] {
|
||||||
base::ObservableViewer(
|
base::ObservableViewer(
|
||||||
Lang::CurrentCloudManager().firstLanguageSuggestion()
|
Lang::CurrentCloudManager().firstLanguageSuggestion()
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
|
@ -425,6 +433,7 @@ void EmojiKeywords::apiChanged(ApiWrap *api) {
|
||||||
}) | rpl::start_with_next([=] {
|
}) | rpl::start_with_next([=] {
|
||||||
refresh();
|
refresh();
|
||||||
}, _suggestedChangeLifetime);
|
}, _suggestedChangeLifetime);
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
_langsRequestId = 0;
|
_langsRequestId = 0;
|
||||||
_suggestedChangeLifetime.destroy();
|
_suggestedChangeLifetime.destroy();
|
||||||
|
@ -452,6 +461,9 @@ std::vector<Result> EmojiKeywords::query(
|
||||||
const QString &query,
|
const QString &query,
|
||||||
bool exact) const {
|
bool exact) const {
|
||||||
const auto normalized = NormalizeQuery(query);
|
const auto normalized = NormalizeQuery(query);
|
||||||
|
if (normalized.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
auto result = std::vector<Result>();
|
auto result = std::vector<Result>();
|
||||||
for (const auto &[language, item] : _data) {
|
for (const auto &[language, item] : _data) {
|
||||||
const auto oldcount = result.size();
|
const auto oldcount = result.size();
|
||||||
|
@ -514,6 +526,10 @@ void EmojiKeywords::setRemoteList(std::vector<QString> &&list) {
|
||||||
if (ranges::find(_remoteList, i->first) != end(_remoteList)) {
|
if (ranges::find(_remoteList, i->first) != end(_remoteList)) {
|
||||||
++i;
|
++i;
|
||||||
} else {
|
} else {
|
||||||
|
if (_notUsedData.size() > kKeepNotUsedLangPacksCount) {
|
||||||
|
_notUsedData.pop_front();
|
||||||
|
}
|
||||||
|
_notUsedData.push_back(std::move(i->second));
|
||||||
i = _data.erase(i);
|
i = _data.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,6 +540,15 @@ void EmojiKeywords::refreshFromRemoteList() {
|
||||||
for (const auto &id : _remoteList) {
|
for (const auto &id : _remoteList) {
|
||||||
if (const auto i = _data.find(id); i != end(_data)) {
|
if (const auto i = _data.find(id); i != end(_data)) {
|
||||||
i->second->refresh();
|
i->second->refresh();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto i = ranges::find(
|
||||||
|
_notUsedData,
|
||||||
|
id,
|
||||||
|
[](const std::unique_ptr<LangPack> &p) { return p->id(); });
|
||||||
|
if (i != end(_notUsedData)) {
|
||||||
|
_data.emplace(id, std::move(*i));
|
||||||
|
_notUsedData.erase(i);
|
||||||
} else {
|
} else {
|
||||||
_data.emplace(
|
_data.emplace(
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -62,6 +62,7 @@ private:
|
||||||
std::vector<QString> _remoteList;
|
std::vector<QString> _remoteList;
|
||||||
mtpRequestId _langsRequestId = 0;
|
mtpRequestId _langsRequestId = 0;
|
||||||
base::flat_map<QString, std::unique_ptr<LangPack>> _data;
|
base::flat_map<QString, std::unique_ptr<LangPack>> _data;
|
||||||
|
std::deque<std::unique_ptr<LangPack>> _notUsedData;
|
||||||
rpl::event_stream<> _refreshed;
|
rpl::event_stream<> _refreshed;
|
||||||
|
|
||||||
rpl::lifetime _suggestedChangeLifetime;
|
rpl::lifetime _suggestedChangeLifetime;
|
||||||
|
|
|
@ -112,7 +112,7 @@ std::vector<SuggestionsWidget::Row> SuggestionsWidget::getRowsByQuery() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
auto suggestions = std::vector<Row>();
|
auto suggestions = std::vector<Row>();
|
||||||
const auto results = Core::App().emojiKeywords().query(_query.mid(1));
|
const auto results = Core::App().emojiKeywords().query(_query);
|
||||||
for (const auto &result : results) {
|
for (const auto &result : results) {
|
||||||
suggestions.emplace_back(
|
suggestions.emplace_back(
|
||||||
result.emoji,
|
result.emoji,
|
||||||
|
@ -475,13 +475,13 @@ QString SuggestionsController::getEmojiQuery() {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cursor = _field->textCursor();
|
const auto cursor = _field->textCursor();
|
||||||
if (cursor.hasSelection()) {
|
if (cursor.hasSelection()) {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto position = cursor.position();
|
const auto position = cursor.position();
|
||||||
auto findTextPart = [this, &position] {
|
const auto findTextPart = [&] {
|
||||||
auto document = _field->document();
|
auto document = _field->document();
|
||||||
auto block = document->findBlock(position);
|
auto block = document->findBlock(position);
|
||||||
for (auto i = block.begin(); !i.atEnd(); ++i) {
|
for (auto i = block.begin(); !i.atEnd(); ++i) {
|
||||||
|
@ -496,18 +496,21 @@ QString SuggestionsController::getEmojiQuery() {
|
||||||
if (fragment.charFormat().isImageFormat()) {
|
if (fragment.charFormat().isImageFormat()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
position -= from;
|
|
||||||
_queryStartPosition = from;
|
_queryStartPosition = from;
|
||||||
return fragment.text();
|
return fragment.text();
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto text = findTextPart();
|
const auto text = findTextPart();
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
for (auto i = position - _queryStartPosition; i != 0;) {
|
||||||
|
if (text[--i] == ':') {
|
||||||
|
return text.mid(i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
const auto isUpperCaseLetter = [](QChar ch) {
|
const auto isUpperCaseLetter = [](QChar ch) {
|
||||||
return (ch >= 'A' && ch <= 'Z');
|
return (ch >= 'A' && ch <= 'Z');
|
||||||
};
|
};
|
||||||
|
@ -568,7 +571,7 @@ QString SuggestionsController::getEmojiQuery() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuggestionsController::replaceCurrent(const QString &replacement) {
|
void SuggestionsController::replaceCurrent(const QString &replacement) {
|
||||||
auto suggestion = getEmojiQuery();
|
const auto suggestion = getEmojiQuery();
|
||||||
if (suggestion.isEmpty()) {
|
if (suggestion.isEmpty()) {
|
||||||
_suggestions->showWithQuery(QString());
|
_suggestions->showWithQuery(QString());
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue