blob: 65e895c1c1ce16b8ca1919e2853acf6e351351f7 [file] [log] [blame]
Andreas Traczyk6ace34f2018-12-14 14:31:23 -05001/**************************************************************************
2* Copyright (C) 2015-2018 by Savoir-faire Linux *
3* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
4* Author: Anthony LĂ©onard <anthony.leonard@savoirfairelinux.com> *
5* Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com> *
6* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> *
7* *
8* This program is free software; you can redistribute it and/or modify *
9* it under the terms of the GNU General Public License as published by *
10* the Free Software Foundation; either version 3 of the License, or *
11* (at your option) any later version. *
12* *
13* This program is distributed in the hope that it will be useful, *
14* but WITHOUT ANY WARRANTY; without even the implied warranty of *
15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16* GNU General Public License for more details. *
17* *
18* You should have received a copy of the GNU General Public License *
19* along with this program. If not, see <http://www.gnu.org/licenses/>. *
20**************************************************************************/
21
22#include "newwizardwidget.h"
23#include "ui_newwizardwidget.h"
24
25#include <QMovie>
26#include <QMessageBox>
27#include <QFileDialog>
28#include <QBitmap>
29
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050030#include "namedirectory.h"
31
32#include "utils.h"
33#include "ringthemeutils.h"
34
35const QString DEFAULT_RING_ACCT_ALIAS = QObject::tr("Jami account", "Default alias for new Jami account");
36
Andreas Traczyk3199a1f2018-12-26 18:20:09 -050037NewWizardWidget::NewWizardWidget(QWidget* parent) :
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050038 NavWidget(parent),
39 ui(new Ui::NewWizardWidget),
Andreas Traczyk3199a1f2018-12-26 18:20:09 -050040 wizardMode_(WizardMode::WIZARD),
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050041 lookupTimer_(this)
42{
43 ui->setupUi(this);
44
45 QPixmap logo(":/images/logo-jami-standard-coul.png");
46
47 ui->welcomeLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation));
48 ui->welcomeLogo->setAlignment(Qt::AlignHCenter);
49
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050050 creationSpinnerMovie_ = new QMovie(":/images/jami_eclipse_spinner.gif");
51 ui->spinnerLabel->setMovie(creationSpinnerMovie_);
52 creationSpinnerMovie_->start();
53
54 lookupSpinnerMovie_ = new QMovie(":/images/jami_rolling_spinner.gif");
55 lookupSpinnerMovie_->setScaledSize(QSize(30, 30));
56
57 lookupStatusLabel_ = new QLabel(this);
58 lookupStatusLabel_->setMovie(lookupSpinnerMovie_);
59 lookupStatusLabel_->hide();
60
61 registrationStateOk_ = false;
62
63 passwordStatusLabel_ = new QLabel(this);
64
65 statusSuccessPixmap_ = Utils::generateTintedPixmap(":/images/icons/baseline-done-24px.svg", RingTheme::presenceGreen_);
66 statusInvalidPixmap_ = Utils::generateTintedPixmap(":/images/icons/baseline-error_outline-24px.svg", RingTheme::urgentOrange_);
67 statusErrorPixmap_ = Utils::generateTintedPixmap(":/images/icons/baseline-close-24px.svg", RingTheme::red_);
68
Andreas Traczyk3199a1f2018-12-26 18:20:09 -050069 ui->infoWidget->hide();
70 setNavBarVisibility(false, true);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050071
72 lookupTimer_.setSingleShot(true);
73
Andreas Traczyk3199a1f2018-12-26 18:20:09 -050074 connect(ui->fileImportBtn, &QPushButton::clicked,
75 [this] {
76 QString filePath;
77 filePath = QFileDialog::getOpenFileName(this,
78 tr("Open File"),
79 QString(),
80 tr("Jami archive files (*.gz); All files (*)"));
81 fileToImport_ = QDir::toNativeSeparators(filePath);
82 if (!fileToImport_.isEmpty()) {
83 QFileInfo fi(filePath);
84 ui->fileImportBtn->setText(fi.fileName());
85 } else {
86 ui->fileImportBtn->setText(tr("(None)"));
87 }
88 validateWizardProgression();
89 });
90
Andreas Traczyk6ace34f2018-12-14 14:31:23 -050091 connect(&lookupTimer_, &QTimer::timeout,
92 this, &NewWizardWidget::timeoutNameLookupTimer);
93
94 connect(ui->backButton, &QPushButton::clicked,
95 [this] {
96 emit NavigationRequested(ScreenEnum::CallScreen);
97 });
98
99 connect(ui->confirmPasswordEdit, &QLineEdit::textChanged,
100 [this] {
101 validateWizardProgression();
102 });
103
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500104 connect(ui->pinEdit, &QLineEdit::textChanged,
105 [this] {
106 validateWizardProgression();
107 });
108
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500109 ui->containerWidget->setVisible(false);
110}
111
112NewWizardWidget::~NewWizardWidget()
113{
114 delete ui;
115}
116
117void
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500118NewWizardWidget::setToMigrate(AccountInfo* toBeMigrated)
119{
120 wizardMode_ = MIGRATION;
121 changePage(ui->createRingAccountPage);
122 ui->usernameEdit->setEnabled(false);
123 ui->usernameEdit->setText(QString::fromStdString(toBeMigrated->profileInfo.alias));
124 ui->previousButton->hide();
125 ui->infoWidget->show();
126 ui->infoLabel->setText(tr("Your account needs to be migrated. Enter your password."));
127}
128
129void
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500130NewWizardWidget::updateNameRegistrationUi(NameRegistrationUIState state)
131{
132 switch (state) {
133 case NameRegistrationUIState::BLANK:
134 lookupStatusLabel_->hide();
135 break;
136 case NameRegistrationUIState::INVALID:
137 lookupStatusLabel_->setPixmap(statusInvalidPixmap_);
138 break;
139 case NameRegistrationUIState::TAKEN:
140 lookupStatusLabel_->setPixmap(statusErrorPixmap_);
141 break;
142 case NameRegistrationUIState::FREE:
143 lookupStatusLabel_->setPixmap(statusSuccessPixmap_);
144 break;
145 case NameRegistrationUIState::SEARCHING:
146 lookupStatusLabel_->setMovie(lookupSpinnerMovie_);
147 lookupSpinnerMovie_->stop();
148 lookupSpinnerMovie_->start();
149 lookupStatusLabel_->show();
150 break;
151 }
152}
153
154void
155NewWizardWidget::navigated(bool to)
156{
157 ui->containerWidget->setVisible(to);
158 changePage(ui->welcomePage);
159 Utils::setStackWidget(ui->stackedWidget, ui->welcomePage);
160}
161
162void
163NewWizardWidget::processWizardInformations()
164{
165 if (wizardMode_ == MIGRATION)
166 ui->progressLabel->setText(tr("Migrating your Jami account..."));
167 else if (wizardMode_ == IMPORT)
168 ui->progressLabel->setText(tr("Importing account archive..."));
169 else
170 ui->progressLabel->setText(tr("Generating your Jami account..."));
171
172 if (wizardMode_ != IMPORT) {
173 QString accountAlias = (ui->fullNameEdit->text().isEmpty() ||
174 ui->fullNameEdit->text().isNull()) ? DEFAULT_RING_ACCT_ALIAS : ui->fullNameEdit->text();
175 QString archivePin = (ui->pinEdit->text().isEmpty() || ui->pinEdit->text().isNull()) ? QString() : ui->pinEdit->text();
176
177 changePage(ui->spinnerPage);
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500178 createRingAccount(accountAlias, ui->passwordEdit->text(), archivePin, fileToImport_);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500179
180 ui->passwordEdit->clear();
181 ui->confirmPasswordEdit->clear();
182 ui->pinEdit->clear();
183 }
184
185 Utils::CreateStartupLink();
186}
187
188void
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500189NewWizardWidget::on_existingPushButton_clicked()
190{
191 changePage(ui->linkRingAccountPage);
192}
193
194void
195NewWizardWidget::on_newAccountButton_clicked()
196{
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500197 changePage(ui->createRingAccountPage);
198}
199
200void NewWizardWidget::changePage(QWidget* toPage)
201{
202 if (toPage == ui->spinnerPage) {
203 setNavBarVisibility(false);
204 }
205 Utils::setStackWidget(ui->stackedWidget, toPage);
206 if (toPage == ui->welcomePage) {
207 setNavBarVisibility(false, true);
208 lookupStatusLabel_->hide();
209 passwordStatusLabel_->hide();
210 } else if (toPage == ui->createRingAccountPage) {
211 ui->usernameEdit->clear();
212 ui->passwordEdit->clear();
213 ui->confirmPasswordEdit->clear();
214 ui->signUpCheckbox->setChecked(true);
215 ui->usernameEdit->setEnabled(true);
Andreas Traczyk6c323c62018-12-26 13:04:22 -0500216 ui->fullNameEdit->setText(Utils::GetCurrentUserName());
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500217 setNavBarVisibility(true);
218 updateCustomUI();
219 registeredNameFoundConnection_ = connect(
220 &LRCInstance::accountModel(), &lrc::api::NewAccountModel::registeredNameFound,
221 this, &NewWizardWidget::slotRegisteredNameFound);
222 validateWizardProgression();
223 ui->setAvatarWidget->startBooth();
224 } else if (toPage == ui->linkRingAccountPage) {
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500225 fileToImport_ = QString("");
226 ui->fileImportBtn->setText(tr("(None)"));
227 ui->pinEdit->clear();
228 ui->importPasswordEdit->clear();
229 ui->pinEdit->setEnabled(true);
230 ui->fileImportBtn->setEnabled(true);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500231 setNavBarVisibility(true);
232 lookupStatusLabel_->hide();
233 passwordStatusLabel_->hide();
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500234 validateWizardProgression();
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500235 } else if (toPage == ui->spinnerPage) {
236 lookupStatusLabel_->hide();
237 passwordStatusLabel_->hide();
238 }
239}
240
241void
242NewWizardWidget::updateCustomUI()
243{
244 QPoint editUsernamePos = ui->usernameEdit->mapTo(this, ui->usernameEdit->rect().topRight());
245 lookupStatusLabel_->setGeometry(editUsernamePos.x() + 6, editUsernamePos.y() - 1, 30, 30);
246 QPoint editconfpassPos = ui->confirmPasswordEdit->mapTo(this, ui->confirmPasswordEdit->rect().topRight());
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500247 passwordStatusLabel_->setGeometry(editconfpassPos.x() + 6, editconfpassPos.y() - 1, 24, 24);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500248}
249
250void
251NewWizardWidget::setNavBarVisibility(bool nav, bool back)
252{
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500253 ui->navBarWidget->setVisible(nav || back);
254 ui->nextButton->setVisible(nav);
255 ui->previousButton->setVisible(nav);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500256 ui->backButton->setVisible(back && LRCInstance::accountModel().getAccountList().size());
257}
258
259void
260NewWizardWidget::on_nextButton_clicked()
261{
262 const QWidget* curWidget = ui->stackedWidget->currentWidget();
Andreas Traczykb96bdd32019-01-02 11:10:16 -0500263 ui->setAvatarWidget->stopBooth();
264 disconnect(registeredNameFoundConnection_);
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500265 if (curWidget == ui->createRingAccountPage ||
266 curWidget == ui->linkRingAccountPage) {
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500267 processWizardInformations();
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500268 }
269}
270
271void
272NewWizardWidget::on_previousButton_clicked()
273{
274 const QWidget* curWidget = ui->stackedWidget->currentWidget();
Andreas Traczykb96bdd32019-01-02 11:10:16 -0500275 ui->setAvatarWidget->stopBooth();
276 disconnect(registeredNameFoundConnection_);
277 lookupStatusLabel_->hide();
278 passwordStatusLabel_->hide();
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500279 if (curWidget == ui->createRingAccountPage ||
280 curWidget == ui->linkRingAccountPage) {
281 changePage(ui->welcomePage);
282 }
283}
284
285void
286NewWizardWidget::on_passwordEdit_textChanged(const QString& arg1)
287{
288 Q_UNUSED(arg1);
289 validateWizardProgression();
290}
291
292void
293NewWizardWidget::on_usernameEdit_textChanged(const QString &arg1)
294{
295 registrationStateOk_ = false;
296 if (ui->signUpCheckbox->isChecked() && !arg1.isEmpty()) {
297 registeredName_ = ui->usernameEdit->text().simplified();
298 lookupTimer_.start(200);
299 } else {
300 updateNameRegistrationUi(NameRegistrationUIState::BLANK);
301 lookupTimer_.stop();
302 if (!arg1.isEmpty()) {
303 lookupTimer_.start(200);
304 }
305 }
306 validateWizardProgression();
307}
308
309void
310NewWizardWidget::timeoutNameLookupTimer()
311{
312 if (ui->signUpCheckbox->isChecked() && !ui->usernameEdit->text().isEmpty()) {
313 updateNameRegistrationUi(NameRegistrationUIState::SEARCHING);
314 NameDirectory::instance().lookupName(nullptr, QString(), registeredName_);
315 }
316}
317
318void
319NewWizardWidget::slotRegisteredNameFound(const std::string& accountId,
320 LookupStatus status,
321 const std::string& address,
322 const std::string& name)
323{
Andreas Traczyk07f83492018-12-26 14:01:46 -0500324 Q_UNUSED(accountId);
325 Q_UNUSED(address);
326
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500327 using namespace lrc::api::account;
328 if (name.length() < 3) {
329 registrationStateOk_ = false;
330 updateNameRegistrationUi(NameRegistrationUIState::INVALID);
331 } else if (registeredName_.toStdString() == name) {
332 switch (status) {
333 case LookupStatus::NOT_FOUND:
334 case LookupStatus::ERROR:
335 registrationStateOk_ = true;
336 updateNameRegistrationUi(NameRegistrationUIState::FREE);
337 break;
338 case LookupStatus::INVALID_NAME:
339 case LookupStatus::INVALID:
340 registrationStateOk_ = false;
341 updateNameRegistrationUi(NameRegistrationUIState::INVALID);
342 break;
343 case LookupStatus::SUCCESS:
344 registrationStateOk_ = false;
345 updateNameRegistrationUi(NameRegistrationUIState::TAKEN);
346 break;
347 }
348 }
349 validateWizardProgression();
350}
351
352void
353NewWizardWidget::handle_nameRegistrationEnded(NameDirectory::RegisterNameStatus status, const QString& name)
354{
355 Q_UNUSED(name);
356 Q_UNUSED(status);
357}
358
359void
360NewWizardWidget::on_signUpCheckbox_toggled(bool checked)
361{
362 if (checked) {
363 ui->usernameEdit->setEnabled(true);
364 } else {
365 ui->usernameEdit->setEnabled(false);
366 ui->usernameEdit->clear();
367 }
368 validateWizardProgression();
369}
370
371void
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500372NewWizardWidget::validateWizardProgression()
373{
Andreas Traczyk3199a1f2018-12-26 18:20:09 -0500374 if (ui->stackedWidget->currentWidget() == ui->linkRingAccountPage) {
375 bool validPin = !ui->pinEdit->text().isEmpty();
376 ui->fileImportBtn->setEnabled(!validPin);
377 ui->fileImportLabel->setEnabled(!validPin);
378 bool validImport = !fileToImport_.isEmpty();
379 ui->pinEdit->setEnabled(!validImport);
380 ui->pinEditLabel->setEnabled(!validImport);
381 ui->nextButton->setEnabled(validPin || validImport);
382 return;
383 }
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500384 bool usernameOk =
385 !ui->signUpCheckbox->isChecked() ||
386 (ui->signUpCheckbox->isChecked() &&
387 !registeredName_.isEmpty() &&
388 (registeredName_ == ui->usernameEdit->text()) &&
389 registrationStateOk_ == true);
390 bool passwordOk = ui->passwordEdit->text() == ui->confirmPasswordEdit->text();
391 if (passwordOk && !ui->passwordEdit->text().isEmpty()) {
392 passwordStatusLabel_->show();
393 passwordStatusLabel_->setPixmap(statusSuccessPixmap_);
394 } else if (!passwordOk) {
395 passwordStatusLabel_->show();
396 passwordStatusLabel_->setPixmap(statusErrorPixmap_);
397 } else {
398 passwordStatusLabel_->hide();
399 }
400 ui->nextButton->setEnabled(usernameOk && passwordOk);
401}
402
403void
404NewWizardWidget::createRingAccount(const QString &displayName,
405 const QString &password,
406 const QString &pin,
407 const QString &archivePath)
408{
Andreas Traczykf9465492019-01-09 13:53:37 -0500409 Utils::oneShotConnect(&LRCInstance::accountModel(), &lrc::api::NewAccountModel::accountAdded,
410 [this](const std::string& accountId) {
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500411 //set default ringtone
412 auto confProps = LRCInstance::accountModel().getAccountConfig(accountId);
413 confProps.Ringtone.ringtonePath = Utils::GetRingtonePath().toStdString();
414 LRCInstance::accountModel().setAccountConfig(accountId, confProps);
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500415 connect(LRCInstance::editableAccountModel(),
416 &lrc::api::NewAccountModel::nameRegistrationEnded,
417 [this] {
418 lrc::api::account::ConfProperties_t accountProperties = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
419 LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), accountProperties);
420 emit NavigationRequested(ScreenEnum::CallScreen);
421 });
Andreas Traczyk3fc824d2019-01-02 15:20:21 -0500422 LRCInstance::editableAccountModel()->registerName(
423 LRCInstance::getCurrAccId(),
424 "",
425 registeredName_.toStdString()
426 );
Andreas Traczyk07f83492018-12-26 14:01:46 -0500427 if (ui->setAvatarWidget->hasAvatar()) {
428 LRCInstance::setCurrAccAvatar(ui->setAvatarWidget->getAvatarPixmap());
429 }
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500430 });
Andreas Traczyk4d23e332019-01-02 10:47:14 -0500431 QtConcurrent::run(
432 [=] {
433 LRCInstance::accountModel().createNewAccount(
434 lrc::api::profile::Type::RING,
435 displayName.toStdString(),
436 archivePath.toStdString(),
437 password.toStdString(),
438 pin.toStdString()
439 );
440 });
Andreas Traczyk6ace34f2018-12-14 14:31:23 -0500441 changePage(ui->spinnerPage);
442 repaint();
443}