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