|  |  | @ -46,7 +46,7 @@ RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent), route_requester_( | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   QFormLayout *layout = new QFormLayout(this); |  |  |  |   QFormLayout *layout = new QFormLayout(this); | 
			
		
	
		
		
			
				
					
					|  |  |  |   layout->addRow(tr("Device"), device_list_ = new QComboBox(this)); |  |  |  |   layout->addRow(tr("Device"), device_list_ = new QComboBox(this)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   layout->addRow(tr("Duration"), period_selector_ = new QComboBox(this)); |  |  |  |   layout->addRow(period_selector_ = new QComboBox(this)); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   layout->addRow(route_list_ = new RouteListWidget(this)); |  |  |  |   layout->addRow(route_list_ = new RouteListWidget(this)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   auto button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |  |  |  |   auto button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); | 
			
		
	
		
		
			
				
					
					|  |  |  |   layout->addRow(button_box); |  |  |  |   layout->addRow(button_box); | 
			
		
	
	
		
		
			
				
					|  |  | @ -57,6 +57,7 @@ RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent), route_requester_( | 
			
		
	
		
		
			
				
					
					|  |  |  |   period_selector_->addItem(tr("Last 2 weeks"), 14); |  |  |  |   period_selector_->addItem(tr("Last 2 weeks"), 14); | 
			
		
	
		
		
			
				
					
					|  |  |  |   period_selector_->addItem(tr("Last month"), 30); |  |  |  |   period_selector_->addItem(tr("Last month"), 30); | 
			
		
	
		
		
			
				
					
					|  |  |  |   period_selector_->addItem(tr("Last 6 months"), 180); |  |  |  |   period_selector_->addItem(tr("Last 6 months"), 180); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   period_selector_->addItem(tr("Preserved"), -1); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Connect signals and slots
 |  |  |  |   // Connect signals and slots
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   QObject::connect(route_requester_, &HttpRequest::requestDone, this, &RoutesDialog::parseRouteList); |  |  |  |   QObject::connect(route_requester_, &HttpRequest::requestDone, this, &RoutesDialog::parseRouteList); | 
			
		
	
	
		
		
			
				
					|  |  | @ -94,35 +95,41 @@ void RoutesDialog::fetchRoutes() { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   route_list_->clear(); |  |  |  |   route_list_->clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   route_list_->setEmptyText(tr("Loading...")); |  |  |  |   route_list_->setEmptyText(tr("Loading...")); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Construct URL with selected device and date range
 |  |  |  |   // Construct URL with selected device and date range
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   auto dongle_id = device_list_->currentData().toString(); |  |  |  |   QString url = QString("%1/v1/devices/%2").arg(CommaApi::BASE_URL, device_list_->currentText()); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   QDateTime current = QDateTime::currentDateTime(); |  |  |  |   int period = period_selector_->currentData().toInt(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   QString url = QString("%1/v1/devices/%2/routes_segments?start=%3&end=%4") |  |  |  |   if (period == -1) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     .arg(CommaApi::BASE_URL).arg(dongle_id) |  |  |  |     url += "/routes/preserved"; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     .arg(current.addDays(-(period_selector_->currentData().toInt())).toMSecsSinceEpoch()) |  |  |  |   } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     .arg(current.toMSecsSinceEpoch()); |  |  |  |     QDateTime now = QDateTime::currentDateTime(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   route_requester_->sendRequest(url); |  |  |  |     url += QString("/routes_segments?start=%1&end=%2") | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                .arg(now.addDays(-period).toMSecsSinceEpoch()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                .arg(now.toMSecsSinceEpoch()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   route_requester_->send(url); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) { |  |  |  | void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (success) { |  |  |  |   if (success) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (const QJsonValue &route : QJsonDocument::fromJson(json.toUtf8()).array()) { |  |  |  |     for (const QJsonValue &route : QJsonDocument::fromJson(json.toUtf8()).array()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       uint64_t start_time = route["start_time_utc_millis"].toDouble(); |  |  |  |       QDateTime from, to; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       uint64_t end_time = route["end_time_utc_millis"].toDouble(); |  |  |  |       if (period_selector_->currentData().toInt() == -1) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       auto datetime = QDateTime::fromMSecsSinceEpoch(start_time); |  |  |  |         from = QDateTime::fromString(route["start_time"].toString(), Qt::ISODateWithMs); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       auto item = new QListWidgetItem(QString("%1    %2min").arg(datetime.toString()).arg((end_time - start_time) / (1000 * 60))); |  |  |  |         to = QDateTime::fromString(route["end_time"].toString(), Qt::ISODateWithMs); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         from = QDateTime::fromMSecsSinceEpoch(route["start_time_utc_millis"].toDouble()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         to = QDateTime::fromMSecsSinceEpoch(route["end_time_utc_millis"].toDouble()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       auto item = new QListWidgetItem(QString("%1    %2min").arg(from.toString()).arg(from.secsTo(to) / 60)); | 
			
		
	
		
		
			
				
					
					|  |  |  |       item->setData(Qt::UserRole, route["fullname"].toString()); |  |  |  |       item->setData(Qt::UserRole, route["fullname"].toString()); | 
			
		
	
		
		
			
				
					
					|  |  |  |       route_list_->addItem(item); |  |  |  |       route_list_->addItem(item); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Select first route if available
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (route_list_->count() > 0) route_list_->setCurrentRow(0); |  |  |  |     if (route_list_->count() > 0) route_list_->setCurrentRow(0); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else { |  |  |  |   } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |     QMessageBox::warning(this, tr("Error"), tr("Failed to fetch routes. Check your network connection.")); |  |  |  |     QMessageBox::warning(this, tr("Error"), tr("Failed to fetch routes. Check your network connection.")); | 
			
		
	
		
		
			
				
					
					|  |  |  |     reject(); |  |  |  |     reject(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |   route_list_->setEmptyText(tr("No items")); |  |  |  |   route_list_->setEmptyText(tr("No items")); | 
			
		
	
		
		
			
				
					
					|  |  |  |   sender()->deleteLater(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | QString RoutesDialog::route() { |  |  |  | QString RoutesDialog::route() { | 
			
		
	
	
		
		
			
				
					|  |  | 
 |