Skip to content

Commit c36a49b

Browse files
tcl3awesomekling
authored andcommitted
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.
1 parent c4d5ae2 commit c36a49b

File tree

2 files changed

+41
-26
lines changed

2 files changed

+41
-26
lines changed

Ladybird/Qt/AutoComplete.cpp

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ AutoComplete::AutoComplete(QWidget* parent)
3838
});
3939
}
4040

41-
ErrorOr<void> AutoComplete::parse_google_autocomplete(Vector<JsonValue> const& json)
41+
ErrorOr<Vector<String>> AutoComplete::parse_google_autocomplete(Vector<JsonValue> const& json)
4242
{
4343
if (json.size() != 5)
4444
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
5454
if (query != m_query)
5555
return Error::from_string_view("Invalid JSON, query does not match"sv);
5656

57-
for (auto& suggestion : suggestions_array) {
58-
m_auto_complete_model->add(TRY(String::from_byte_string(suggestion.as_string())));
59-
}
57+
Vector<String> results;
58+
results.ensure_capacity(suggestions_array.size());
59+
for (auto& suggestion : suggestions_array)
60+
results.unchecked_append(MUST(String::from_byte_string(suggestion.as_string())));
6061

61-
return {};
62+
return results;
6263
}
6364

64-
ErrorOr<void> AutoComplete::parse_duckduckgo_autocomplete(Vector<JsonValue> const& json)
65+
ErrorOr<Vector<String>> AutoComplete::parse_duckduckgo_autocomplete(Vector<JsonValue> const& json)
6566
{
67+
Vector<String> results;
6668
for (auto const& suggestion : json) {
6769
auto maybe_value = suggestion.as_object().get("phrase"sv);
6870
if (!maybe_value.has_value())
6971
continue;
70-
m_auto_complete_model->add(TRY(String::from_byte_string(maybe_value->as_string())));
72+
results.append(MUST(String::from_byte_string(maybe_value->as_string())));
7173
}
7274

73-
return {};
75+
return results;
7476
}
7577

76-
ErrorOr<void> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
78+
ErrorOr<Vector<String>> AutoComplete::parse_yahoo_autocomplete(JsonObject const& json)
7779
{
7880
if (!json.get("q"sv).has_value() || !json.get("q"sv)->is_string())
7981
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)
8688
if (query != m_query)
8789
return Error::from_string_view("Invalid JSON, query does not match"sv);
8890

91+
Vector<String> results;
92+
results.ensure_capacity(suggestions_object.size());
8993
for (auto& suggestion_object : suggestions_object) {
9094
if (!suggestion_object.is_object())
9195
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)
9498
if (!suggestion.get("k"sv).has_value() || !suggestion.get("k"sv)->is_string())
9599
return Error::from_string_view("Invalid JSON, expected \"k\" to be a string"sv);
96100

97-
m_auto_complete_model->add(TRY(String::from_byte_string(suggestion.get("k"sv)->as_string())));
98-
};
101+
results.unchecked_append(MUST(String::from_byte_string(suggestion.get("k"sv)->as_string())));
102+
}
99103

100-
return {};
104+
return results;
101105
}
102106

103107
ErrorOr<void> AutoComplete::got_network_response(QNetworkReply* reply)
@@ -109,16 +113,23 @@ ErrorOr<void> AutoComplete::got_network_response(QNetworkReply* reply)
109113
auto json = TRY(parser.parse());
110114

111115
auto engine_name = Settings::the()->autocomplete_engine().name;
112-
if (engine_name == "Google")
113-
return parse_google_autocomplete(json.as_array().values());
114-
115-
if (engine_name == "DuckDuckGo")
116-
return parse_duckduckgo_autocomplete(json.as_array().values());
116+
Vector<String> results;
117+
if (engine_name == "Google") {
118+
results = TRY(parse_google_autocomplete(json.as_array().values()));
119+
} else if (engine_name == "DuckDuckGo") {
120+
results = TRY(parse_duckduckgo_autocomplete(json.as_array().values()));
121+
} else if (engine_name == "Yahoo")
122+
results = TRY(parse_yahoo_autocomplete(json.as_object()));
123+
else {
124+
return Error::from_string_view("Invalid engine name"sv);
125+
}
117126

118-
if (engine_name == "Yahoo")
119-
return parse_yahoo_autocomplete(json.as_object());
127+
if (results.is_empty()) {
128+
results.append(m_query);
129+
}
120130

121-
return Error::from_string_view("Invalid engine name"sv);
131+
m_auto_complete_model->replace_suggestions(move(results));
132+
return {};
122133
}
123134

124135
String AutoComplete::auto_complete_url_from_query(StringView query)
@@ -138,9 +149,6 @@ void AutoComplete::get_search_suggestions(String search_string)
138149
if (m_reply)
139150
m_reply->abort();
140151

141-
m_auto_complete_model->clear();
142-
m_auto_complete_model->add(m_query);
143-
144152
QNetworkRequest request { QUrl(qstring_from_ak_string(auto_complete_url_from_query(m_query))) };
145153
m_reply = m_manager->get(request);
146154
}

Ladybird/Qt/AutoComplete.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ class AutoCompleteModel final : public QAbstractListModel {
4545
endResetModel();
4646
}
4747

48+
void replace_suggestions(Vector<String> suggestions)
49+
{
50+
beginInsertRows({}, m_suggestions.size(), m_suggestions.size());
51+
m_suggestions = suggestions;
52+
endInsertRows();
53+
}
54+
4855
private:
4956
AK::Vector<String> m_suggestions;
5057
};
@@ -71,9 +78,9 @@ class AutoComplete final : public QCompleter {
7178

7279
ErrorOr<void> got_network_response(QNetworkReply* reply);
7380

74-
ErrorOr<void> parse_google_autocomplete(Vector<JsonValue> const&);
75-
ErrorOr<void> parse_duckduckgo_autocomplete(Vector<JsonValue> const&);
76-
ErrorOr<void> parse_yahoo_autocomplete(JsonObject const&);
81+
ErrorOr<Vector<String>> parse_google_autocomplete(Vector<JsonValue> const&);
82+
ErrorOr<Vector<String>> parse_duckduckgo_autocomplete(Vector<JsonValue> const&);
83+
ErrorOr<Vector<String>> parse_yahoo_autocomplete(JsonObject const&);
7784

7885
QNetworkAccessManager* m_manager;
7986
AutoCompleteModel* m_auto_complete_model;

0 commit comments

Comments
 (0)