feat(travel): Optimize arrival data updates and enhance UI responsiveness
This commit is contained in:
@@ -160,8 +160,10 @@ void MainUI::update_arrivals(const std::vector<RouteArrivalData>& arrival_data)
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide message label
|
||||
lv_obj_add_flag(msg_label_, LV_OBJ_FLAG_HIDDEN);
|
||||
// Hide message label only if it's currently visible
|
||||
if (!lv_obj_has_flag(msg_label_, LV_OBJ_FLAG_HIDDEN)) {
|
||||
lv_obj_add_flag(msg_label_, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
// Update each route display
|
||||
for (int i = 0; i < MAX_DISPLAY_ROUTES; i++) {
|
||||
@@ -186,16 +188,20 @@ void MainUI::update_route_display_(RouteDisplay& display, const RouteArrivalData
|
||||
display.cached_visible = true;
|
||||
}
|
||||
|
||||
// Update header with line color
|
||||
// Update header text (station -> direction)
|
||||
std::string header_text = data.route.station_name + " -> " + data.route.direction_name;
|
||||
if (header_text != display.cached_header_text) {
|
||||
lv_label_set_text(display.header, header_text.c_str());
|
||||
display.cached_header_text = header_text;
|
||||
}
|
||||
|
||||
if (!data.route.line_color.empty()) {
|
||||
lv_color_t line_color = hex_to_lv_color_(data.route.line_color);
|
||||
lv_obj_set_style_text_color(display.header, line_color, 0);
|
||||
// Update line color only if changed
|
||||
if (data.route.line_color != display.cached_line_color) {
|
||||
if (!data.route.line_color.empty()) {
|
||||
lv_color_t line_color = hex_to_lv_color_(data.route.line_color);
|
||||
lv_obj_set_style_text_color(display.header, line_color, 0);
|
||||
}
|
||||
display.cached_line_color = data.route.line_color;
|
||||
}
|
||||
|
||||
// Update arrival labels - only if text changed
|
||||
@@ -217,23 +223,28 @@ void MainUI::update_route_display_(RouteDisplay& display, const RouteArrivalData
|
||||
display.cached_arrival_texts[i] = arrival_text;
|
||||
}
|
||||
|
||||
// Handle visibility
|
||||
if (should_show) {
|
||||
if (lv_obj_has_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN)) {
|
||||
// Handle visibility only if changed
|
||||
if (should_show != display.cached_arrival_visible[i]) {
|
||||
if (should_show) {
|
||||
lv_obj_clear_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
} else {
|
||||
if (!lv_obj_has_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN)) {
|
||||
} else {
|
||||
lv_obj_add_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
display.cached_arrival_visible[i] = should_show;
|
||||
}
|
||||
}
|
||||
|
||||
// Show error if any
|
||||
if (!data.is_valid && !data.error_message.empty()) {
|
||||
std::string error_text = " 錯誤: " + data.error_message;
|
||||
lv_label_set_text(display.arrival_labels[0], error_text.c_str());
|
||||
lv_obj_clear_flag(display.arrival_labels[0], LV_OBJ_FLAG_HIDDEN);
|
||||
if (error_text != display.cached_arrival_texts[0]) {
|
||||
lv_label_set_text(display.arrival_labels[0], error_text.c_str());
|
||||
display.cached_arrival_texts[0] = error_text;
|
||||
}
|
||||
if (!display.cached_arrival_visible[0]) {
|
||||
lv_obj_clear_flag(display.arrival_labels[0], LV_OBJ_FLAG_HIDDEN);
|
||||
display.cached_arrival_visible[0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +255,10 @@ void MainUI::update_last_refresh_time(const std::string& time_str) {
|
||||
}
|
||||
|
||||
std::string full_text = "更新: " + time_str;
|
||||
lv_label_set_text(refresh_time_label_, full_text.c_str());
|
||||
if (full_text != cached_refresh_time_text) {
|
||||
lv_label_set_text(refresh_time_label_, full_text.c_str());
|
||||
cached_refresh_time_text = full_text;
|
||||
}
|
||||
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ private:
|
||||
lv_obj_t* settings_btn_ = nullptr;
|
||||
lv_obj_t* refresh_time_label_ = nullptr;
|
||||
lv_obj_t* msg_label_ = nullptr;
|
||||
std::string cached_refresh_time_text;
|
||||
|
||||
// Route display containers (up to MAX_ROUTES)
|
||||
struct RouteDisplay {
|
||||
@@ -46,7 +47,9 @@ private:
|
||||
|
||||
// Cached values for change detection
|
||||
std::string cached_header_text;
|
||||
std::string cached_line_color;
|
||||
std::string cached_arrival_texts[3];
|
||||
bool cached_arrival_visible[3] = {false, false, false};
|
||||
bool cached_visible = false;
|
||||
};
|
||||
RouteDisplay route_displays_[5];
|
||||
|
||||
@@ -238,8 +238,11 @@ void MainUIHandler::fetch_and_update_arrivals_() {
|
||||
arrival_data.push_back(data);
|
||||
}
|
||||
|
||||
// Update UI
|
||||
main_ui_->update_arrivals(arrival_data);
|
||||
// Update UI only if data changed
|
||||
if (has_arrival_data_changed_(arrival_data)) {
|
||||
main_ui_->update_arrivals(arrival_data);
|
||||
cached_arrival_data_ = arrival_data;
|
||||
}
|
||||
main_ui_->update_last_refresh_time(get_current_time_string_());
|
||||
}
|
||||
|
||||
@@ -296,6 +299,37 @@ std::string MainUIHandler::get_current_time_string_() {
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
bool MainUIHandler::has_arrival_data_changed_(const std::vector<RouteArrivalData>& new_data) {
|
||||
if (new_data.size() != cached_arrival_data_.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < new_data.size(); i++) {
|
||||
const auto& new_route = new_data[i];
|
||||
const auto& cached_route = cached_arrival_data_[i];
|
||||
|
||||
if (new_route.route.station_code != cached_route.route.station_code ||
|
||||
new_route.route.direction != cached_route.route.direction ||
|
||||
new_route.is_valid != cached_route.is_valid ||
|
||||
new_route.error_message != cached_route.error_message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new_route.arrivals.size() != cached_route.arrivals.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < new_route.arrivals.size(); j++) {
|
||||
if (new_route.arrivals[j].arrival_time != cached_route.arrivals[j].arrival_time ||
|
||||
new_route.arrivals[j].arrival_time_full != cached_route.arrivals[j].arrival_time_full) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainUIHandler::on_settings_button_clicked_static_(lv_event_t* e) {
|
||||
MainUIHandler* handler = static_cast<MainUIHandler*>(lv_event_get_user_data(e));
|
||||
if (handler) {
|
||||
|
||||
@@ -47,6 +47,7 @@ private:
|
||||
|
||||
void on_settings_button_clicked_();
|
||||
void fetch_and_update_arrivals_();
|
||||
bool has_arrival_data_changed_(const std::vector<RouteArrivalData>& new_data);
|
||||
std::string format_arrival_time_(const std::string& api_time);
|
||||
std::string format_arrival_time_full_(const std::string& api_time);
|
||||
std::string get_current_time_string_();
|
||||
@@ -65,6 +66,8 @@ private:
|
||||
SettingsButtonCallback on_settings_callback_ = nullptr;
|
||||
void* settings_callback_user_data_ = nullptr;
|
||||
|
||||
std::vector<RouteArrivalData> cached_arrival_data_;
|
||||
|
||||
static constexpr uint32_t LVGL_LOCK_TIMEOUT_MS = 4000;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user