feat(travel): Enhance MTR arrival handling with retry logic and improve UI update efficiency
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user