|  |  | @ -1,54 +1,41 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <string> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "onboarding.hpp" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <QStackedLayout> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <QVBoxLayout> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <QHBoxLayout> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <QPushButton> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <QLabel> |  |  |  | #include <QLabel> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <QString> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <QPushButton> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <QGridLayout> | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include "onboarding.hpp" | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "common/params.h" |  |  |  | #include "common/params.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | QLabel * title_label(QString text) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QLabel *l = new QLabel(text); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   l->setStyleSheet(R"(font-size: 100px;)"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   l->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return l; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | QWidget * OnboardingWindow::terms_screen() { |  |  |  | QWidget * OnboardingWindow::terms_screen() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   QVBoxLayout *main_layout = new QVBoxLayout(); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QGridLayout *main_layout = new QGridLayout(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   main_layout->setMargin(30); |  |  |  |   main_layout->setMargin(30); | 
			
		
	
		
		
			
				
					
					|  |  |  |   main_layout->setSpacing(30); |  |  |  |   main_layout->setSpacing(30); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   QLabel *title = new QLabel("Review Terms"); |  |  |  |   main_layout->addWidget(title_label("Review Terms"), 0, 0, 1, -1); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   title->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   title->setStyleSheet(R"( |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     QLabel { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       font-size: 80px; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       text-align: left; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       margin: 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       padding: 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   )"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   main_layout->addWidget(title); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   QLabel *terms = new QLabel("See terms at https://my.comma.ai/terms"); |  |  |  |   QLabel *terms = new QLabel("See terms at https://my.comma.ai/terms"); | 
			
		
	
		
		
			
				
					
					|  |  |  |   terms->setAlignment(Qt::AlignCenter); |  |  |  |   terms->setAlignment(Qt::AlignCenter); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   terms->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | 
			
		
	
		
		
			
				
					
					|  |  |  |   terms->setStyleSheet(R"( |  |  |  |   terms->setStyleSheet(R"( | 
			
		
	
		
		
			
				
					
					|  |  |  |     QLabel { |  |  |  |     font-size: 75px; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       font-size: 35px; |  |  |  |     border-radius: 10px; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       border-radius: 10px; |  |  |  |     background-color: #292929; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       text-align: center; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       background-color: #292929; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   )"); |  |  |  |   )"); | 
			
		
	
		
		
			
				
					
					|  |  |  |   main_layout->addWidget(terms, Qt::AlignTop); |  |  |  |   main_layout->addWidget(terms, 1, 0, 1, -1); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   QHBoxLayout *btn_layout = new QHBoxLayout(); |  |  |  |   main_layout->addWidget(new QPushButton("Decline"), 2, 0); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   //btn_layout->setSpacing(30);
 |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   QPushButton *decline_btn = new QPushButton("Decline"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   btn_layout->addWidget(decline_btn); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   QPushButton *accept_btn = new QPushButton("Accept"); |  |  |  |   QPushButton *accept_btn = new QPushButton("Accept"); | 
			
		
	
		
		
			
				
					
					|  |  |  |   btn_layout->addWidget(accept_btn); |  |  |  |   main_layout->addWidget(accept_btn, 2, 1); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   main_layout->addLayout(btn_layout); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   QObject::connect(accept_btn, &QPushButton::released, [=]() { |  |  |  |   QObject::connect(accept_btn, &QPushButton::released, [=]() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     Params().write_db_value("HasAcceptedTerms", LATEST_TERMS_VERSION); |  |  |  |     Params().write_db_value("HasAcceptedTerms", LATEST_TERMS_VERSION); | 
			
		
	
		
		
			
				
					
					|  |  |  |     updateActiveScreen(); |  |  |  |     updateActiveScreen(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -57,9 +44,6 @@ QWidget * OnboardingWindow::terms_screen() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   QWidget *widget = new QWidget; |  |  |  |   QWidget *widget = new QWidget; | 
			
		
	
		
		
			
				
					
					|  |  |  |   widget->setLayout(main_layout); |  |  |  |   widget->setLayout(main_layout); | 
			
		
	
		
		
			
				
					
					|  |  |  |   widget->setStyleSheet(R"( |  |  |  |   widget->setStyleSheet(R"( | 
			
		
	
		
		
			
				
					
					|  |  |  |     QLabel { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       color: white; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     QPushButton { |  |  |  |     QPushButton { | 
			
		
	
		
		
			
				
					
					|  |  |  |       font-size: 50px; |  |  |  |       font-size: 50px; | 
			
		
	
		
		
			
				
					
					|  |  |  |       padding: 50px; |  |  |  |       padding: 50px; | 
			
		
	
	
		
		
			
				
					|  |  | @ -71,33 +55,58 @@ QWidget * OnboardingWindow::terms_screen() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   return widget; |  |  |  |   return widget; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | QWidget * OnboardingWindow::training_screen() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QGridLayout *main_layout = new QGridLayout(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   main_layout->setMargin(30); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   main_layout->setSpacing(30); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   main_layout->addWidget(title_label("Training Guide"), 0, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QPushButton *btn = new QPushButton("Continue"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   main_layout->addWidget(btn, 1, 0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QObject::connect(btn, &QPushButton::released, [=]() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Params().write_db_value("CompletedTrainingVersion", LATEST_TRAINING_VERSION); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     updateActiveScreen(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   }); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QWidget *widget = new QWidget; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   widget->setLayout(main_layout); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return widget; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void OnboardingWindow::updateActiveScreen() { |  |  |  | void OnboardingWindow::updateActiveScreen() { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   Params params = Params(); |  |  |  |   Params params = Params(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool accepted_terms = params.get("HasAcceptedTerms", false).compare(LATEST_TERMS_VERSION) == 0; |  |  |  |   bool accepted_terms = params.get("HasAcceptedTerms", false).compare(LATEST_TERMS_VERSION) == 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   bool training_done = params.get("CompletedTrainingVersion", false).compare(LATEST_TRAINING_VERSION) == 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (accepted_terms) { |  |  |  |   if (!accepted_terms) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     layout->setCurrentIndex(0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } else if (!training_done) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     layout->setCurrentIndex(1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |     emit onboardingDone(); |  |  |  |     emit onboardingDone(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | OnboardingWindow::OnboardingWindow(QWidget *parent) : QWidget(parent) { |  |  |  | OnboardingWindow::OnboardingWindow(QWidget *parent) : QWidget(parent) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   layout = new QStackedLayout(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   layout->addWidget(terms_screen()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   layout->addWidget(training_screen()); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Onboarding flow: terms -> account pairing -> training
 |  |  |  |   setLayout(layout); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   QStackedLayout *main_layout = new QStackedLayout; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   main_layout->addWidget(terms_screen()); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   setLayout(main_layout); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   setStyleSheet(R"( |  |  |  |   setStyleSheet(R"( | 
			
		
	
		
		
			
				
					
					|  |  |  |     * { |  |  |  |     * { | 
			
		
	
		
		
			
				
					
					|  |  |  |       background-color: black; |  |  |  |       background-color: black; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     QPushButton { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       font-size: 50px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       padding: 50px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       border-radius: 10px; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       background-color: #292929; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   )"); |  |  |  |   )"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   // TODO: implement the training guide
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   Params().write_db_value("CompletedTrainingVersion", LATEST_TRAINING_VERSION); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   updateActiveScreen(); |  |  |  |   updateActiveScreen(); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |