mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 17:31:58 -05:00
UI/Qt: Reduce flicker when populating autocomplete
Previously, autocomplete was cleared before the results for the current query were retrieved. The new results would then be added when the network request completed. This resulted in a noticable flicker. The results are now updated when the request for the current query is completed. There is a small behavior change in that the query itself is no longer included in the autocomplete dropdown unless the list would otherwise be empty. (cherry picked from commit c36a49b61eeaa7f892c4f2ca844891eb13295ffb)
This commit is contained in:
parent
73e0d101d9
commit
5439340808
2 changed files with 41 additions and 26 deletions
|
@ -38,7 +38,7 @@ AutoComplete::AutoComplete(QWidget* parent)
|
|||
});
|
||||
}
|
||||
|
||||
ErrorOr<void> AutoComplete::parse_google_autocomplete(Vector<JsonValue> const& json)
|
||||
ErrorOr<Vector<String>> AutoComplete::parse_google_autocomplete(Vector<JsonValue> const& json)
|
||||
{
|
||||
if (json.size() != 5)
|
||||
return Error::from_string_view("Invalid JSON, expected 5 elements in array"sv);
|
||||
|
@ -54,26 +54,28 @@ ErrorOr<void> AutoComplete::parse_google_autocomplete(Vector<JsonValue> const& j
|
|||
if (query != m_query)
|
||||
return Error::from_string_view("Invalid JSON, query does not match"sv);
|
||||
|
||||
for (auto& suggestion : suggestions_array) {
|
||||
m_auto_complete_model->add(TRY(String::from_byte_string(suggestion.as_string())));
|
||||
}
|
||||
Vector<String> results;
|
||||
results.ensure_capacity(suggestions_array.size());
|
||||
for (auto& suggestion : suggestions_array)
|
||||
results.unchecked_append(MUST(String::from_byte_string(suggestion.as_string())));
|
||||
|
||||
return {};
|
||||
return results;
|
||||
}
|
||||
|
||||
ErrorOr<void> AutoComplete::parse_duckduckgo_autocomplete(Vector<JsonValue> const& json)
|
||||
ErrorOr<Vector<String>> AutoComplete::parse_duckduckgo_autocomplete(Vector<JsonValue> const& json)
|
||||
{
|
||||
Vector<String> results;
|
||||
for (auto const& suggestion : json) {
|
||||
auto maybe_value = suggestion.as_object().get("phrase"sv);
|
||||
if (!maybe_value.has_value())
|
||||
continue;
|
||||
m_auto_complete_model->add(TRY(String::from_byte_string(maybe_value->as_string())));
|
||||
results.append(MUST(String::from_byte_string(maybe_value->as_string())));
|
||||
}
|
||||
|
||||
return {};
|
||||
return results;
|
||||
}
|
||||
|
||||
ErrorOr<void> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
|
||||
ErrorOr<Vector<String>> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
|
||||
{
|
||||
if (!json.get("q"sv).has_value() || !json.get("q"sv)->is_string())
|
||||
return Error::from_string_view("Invalid JSON, expected \"q\" to be a string"sv);
|
||||
|
@ -86,6 +88,8 @@ ErrorOr<void> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
|
|||
if (query != m_query)
|
||||
return Error::from_string_view("Invalid JSON, query does not match"sv);
|
||||
|
||||
Vector<String> results;
|
||||
results.ensure_capacity(suggestions_object.size());
|
||||
for (auto& suggestion_object : suggestions_object) {
|
||||
if (!suggestion_object.is_object())
|
||||
return Error::from_string_view("Invalid JSON, expected value to be an object"sv);
|
||||
|
@ -94,10 +98,10 @@ ErrorOr<void> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
|
|||
if (!suggestion.get("k"sv).has_value() || !suggestion.get("k"sv)->is_string())
|
||||
return Error::from_string_view("Invalid JSON, expected \"k\" to be a string"sv);
|
||||
|
||||
m_auto_complete_model->add(TRY(String::from_byte_string(suggestion.get("k"sv)->as_string())));
|
||||
};
|
||||
results.unchecked_append(MUST(String::from_byte_string(suggestion.get("k"sv)->as_string())));
|
||||
}
|
||||
|
||||
return {};
|
||||
return results;
|
||||
}
|
||||
|
||||
ErrorOr<void> AutoComplete::got_network_response(QNetworkReply* reply)
|
||||
|
@ -109,16 +113,23 @@ ErrorOr<void> AutoComplete::got_network_response(QNetworkReply* reply)
|
|||
auto json = TRY(parser.parse());
|
||||
|
||||
auto engine_name = Settings::the()->autocomplete_engine().name;
|
||||
if (engine_name == "Google")
|
||||
return parse_google_autocomplete(json.as_array().values());
|
||||
Vector<String> results;
|
||||
if (engine_name == "Google") {
|
||||
results = TRY(parse_google_autocomplete(json.as_array().values()));
|
||||
} else if (engine_name == "DuckDuckGo") {
|
||||
results = TRY(parse_duckduckgo_autocomplete(json.as_array().values()));
|
||||
} else if (engine_name == "Yahoo")
|
||||
results = TRY(parse_yahoo_autocomplete(json.as_object()));
|
||||
else {
|
||||
return Error::from_string_view("Invalid engine name"sv);
|
||||
}
|
||||
|
||||
if (engine_name == "DuckDuckGo")
|
||||
return parse_duckduckgo_autocomplete(json.as_array().values());
|
||||
if (results.is_empty()) {
|
||||
results.append(m_query);
|
||||
}
|
||||
|
||||
if (engine_name == "Yahoo")
|
||||
return parse_yahoo_autocomplete(json.as_object());
|
||||
|
||||
return Error::from_string_view("Invalid engine name"sv);
|
||||
m_auto_complete_model->replace_suggestions(move(results));
|
||||
return {};
|
||||
}
|
||||
|
||||
String AutoComplete::auto_complete_url_from_query(StringView query)
|
||||
|
@ -138,9 +149,6 @@ void AutoComplete::get_search_suggestions(String search_string)
|
|||
if (m_reply)
|
||||
m_reply->abort();
|
||||
|
||||
m_auto_complete_model->clear();
|
||||
m_auto_complete_model->add(m_query);
|
||||
|
||||
QNetworkRequest request { QUrl(qstring_from_ak_string(auto_complete_url_from_query(m_query))) };
|
||||
m_reply = m_manager->get(request);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,13 @@ public:
|
|||
endResetModel();
|
||||
}
|
||||
|
||||
void replace_suggestions(Vector<String> suggestions)
|
||||
{
|
||||
beginInsertRows({}, m_suggestions.size(), m_suggestions.size());
|
||||
m_suggestions = suggestions;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
private:
|
||||
AK::Vector<String> m_suggestions;
|
||||
};
|
||||
|
@ -71,9 +78,9 @@ private:
|
|||
|
||||
ErrorOr<void> got_network_response(QNetworkReply* reply);
|
||||
|
||||
ErrorOr<void> parse_google_autocomplete(Vector<JsonValue> const&);
|
||||
ErrorOr<void> parse_duckduckgo_autocomplete(Vector<JsonValue> const&);
|
||||
ErrorOr<void> parse_yahoo_autocomplete(JsonObject const&);
|
||||
ErrorOr<Vector<String>> parse_google_autocomplete(Vector<JsonValue> const&);
|
||||
ErrorOr<Vector<String>> parse_duckduckgo_autocomplete(Vector<JsonValue> const&);
|
||||
ErrorOr<Vector<String>> parse_yahoo_autocomplete(JsonObject const&);
|
||||
|
||||
QNetworkAccessManager* m_manager;
|
||||
AutoCompleteModel* m_auto_complete_model;
|
||||
|
|
Loading…
Reference in a new issue