feat(travel): Enhance MTR arrival handling with retry logic and improve UI update efficiency

This commit is contained in:
GW_MC
2026-02-03 20:49:42 +08:00
parent 3617a206ff
commit 6c4050e9d4
4 changed files with 100 additions and 32 deletions

View File

@@ -167,8 +167,11 @@ void MainUI::update_arrivals(const std::vector<RouteArrivalData>& arrival_data)
if (i < static_cast<int>(arrival_data.size())) {
update_route_display_(route_displays_[i], arrival_data[i]);
} else {
// Hide unused route displays
lv_obj_add_flag(route_displays_[i].container, LV_OBJ_FLAG_HIDDEN);
// Hide unused route displays if currently visible
if (route_displays_[i].cached_visible) {
lv_obj_add_flag(route_displays_[i].container, LV_OBJ_FLAG_HIDDEN);
route_displays_[i].cached_visible = false;
}
}
}
@@ -176,37 +179,59 @@ void MainUI::update_arrivals(const std::vector<RouteArrivalData>& arrival_data)
}
void MainUI::update_route_display_(RouteDisplay& display, const RouteArrivalData& data) {
lv_obj_clear_flag(display.container, LV_OBJ_FLAG_HIDDEN);
// Show container if hidden
if (!display.cached_visible) {
lv_obj_clear_flag(display.container, LV_OBJ_FLAG_HIDDEN);
display.cached_visible = true;
}
// Update header with line color
std::string header_text = data.route.station_name + "" + data.route.direction_name;
lv_label_set_text(display.header, header_text.c_str());
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 arrival labels
// Update arrival labels - only if text changed
for (int i = 0; i < MAX_ARRIVALS_PER_ROUTE; i++) {
if (i < static_cast<int>(data.arrivals.size())) {
std::string arrival_text = "";
bool should_show = (i < static_cast<int>(data.arrivals.size()));
if (should_show) {
const auto& arrival = data.arrivals[i];
std::string arrival_text = " " + arrival.arrival_time;
arrival_text = " " + arrival.arrival_time;
if (!arrival.arrival_time_full.empty()) {
arrival_text += " (" + arrival.arrival_time_full + ")";
}
arrival_text += " " + arrival.direction;
}
if (arrival_text != display.cached_arrival_texts[i]) {
lv_label_set_text(display.arrival_labels[i], arrival_text.c_str());
lv_obj_clear_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN);
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)) {
lv_obj_clear_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN);
}
} else {
lv_label_set_text(display.arrival_labels[i], "");
lv_obj_add_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN);
if (!lv_obj_has_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN)) {
lv_obj_add_flag(display.arrival_labels[i], LV_OBJ_FLAG_HIDDEN);
}
}
}
// Show error if any
if (!data.is_valid && !data.error_message.empty()) {
lv_label_set_text(display.arrival_labels[0], (" 錯誤: " + data.error_message).c_str());
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);
}
}

View File

@@ -43,6 +43,11 @@ private:
lv_obj_t* container = nullptr;
lv_obj_t* header = nullptr;
lv_obj_t* arrival_labels[3] = {nullptr, nullptr, nullptr}; // Show up to 3 arrivals per route
// Cached values for change detection
std::string cached_header_text;
std::string cached_arrival_texts[3];
bool cached_visible = false;
};
RouteDisplay route_displays_[5];

View File

@@ -258,7 +258,18 @@ std::string MainUIHandler::format_arrival_time_(const std::string& api_time) {
return time_part;
}
return api_time;
// Try to find HH:MM pattern in the string
for (size_t i = 0; i < api_time.length() - 5; i++) {
if (api_time[i] == ':' && i > 0 && i < api_time.length() - 3) {
std::string candidate = api_time.substr(i - 2, 5);
if (isdigit(candidate[0]) && isdigit(candidate[1]) && candidate[2] == ':' &&
isdigit(candidate[3]) && isdigit(candidate[4])) {
return candidate;
}
}
}
return ""; // Return empty instead of raw input
}
std::string MainUIHandler::format_arrival_time_full_(const std::string& api_time) {
@@ -280,8 +291,8 @@ std::string MainUIHandler::get_current_time_string_() {
auto now = std::time(nullptr);
auto tm = *std::localtime(&now);
char buffer[9]; // HH:MM:SS\0
strftime(buffer, sizeof(buffer), "%H:%M:%S", &tm);
char buffer[6]; // HH:MM\0
strftime(buffer, sizeof(buffer), "%H:%M", &tm);
return std::string(buffer);
}