From 026a84b431e8e96acf03e8325b7a1fceb6028e94 Mon Sep 17 00:00:00 2001
From: Nicolas Jager <nicolas.jager@savoirfairelinux.com>
Date: Mon, 28 Nov 2016 10:58:22 -0500
Subject: [PATCH] Account : improvement for add existing account

Change-Id: Ibdeb9f48d881e42c67e011d8db4cdf524f7eb55a
Tuleap: #790
---
 MainPage.xaml.cpp   |  19 ++++-
 MainPage.xaml.h     |   2 +
 RingD.cpp           |  24 +++++-
 RingD.h             |   4 +
 SmartPanel.xaml     | 112 ++++++++++++++++++++++++++--
 SmartPanel.xaml.cpp | 174 ++++++++++++++++++++++++++++++++++----------
 SmartPanel.xaml.h   |   9 +++
 Wizard.xaml         |   9 ++-
 Wizard.xaml.cpp     |  13 ++++
 Wizard.xaml.h       |   2 +
 10 files changed, 313 insertions(+), 55 deletions(-)

diff --git a/MainPage.xaml.cpp b/MainPage.xaml.cpp
index 1b01950..7914e55 100644
--- a/MainPage.xaml.cpp
+++ b/MainPage.xaml.cpp
@@ -84,10 +84,9 @@ MainPage::MainPage()
 
     visibilityChangedEventToken = Window::Current->VisibilityChanged +=
                                       ref new WindowVisibilityChangedEventHandler(this, &MainPage::Application_VisibilityChanged);
-    /*applicationSuspendingEventToken = Application::Current->Suspending +=
-                                          ref new SuspendingEventHandler(this, &MainPage::Application_Suspending);
-    applicationResumingEventToken = Application::Current->Resuming +=
-                                        ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);*/
+    ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);
+    RingD::instance->registrationStateErrorGeneric += ref new RingClientUWP::RegistrationStateErrorGeneric(this, &RingClientUWP::MainPage::OnregistrationStateErrorGeneric);
+    RingD::instance->registrationStateRegistered += ref new RingClientUWP::RegistrationStateRegistered(this, &RingClientUWP::MainPage::OnregistrationStateRegistered);
 }
 
 void
@@ -437,3 +436,15 @@ void RingClientUWP::MainPage::OncloseMessageTextPage()
     auto smartPanel = dynamic_cast<SmartPanel^>(_smartPanel_->Content);
     smartPanel->unselectContact();
 }
+
+
+void RingClientUWP::MainPage::OnregistrationStateErrorGeneric(const std::string& accountId)
+{
+    showLoadingOverlay(false, false);
+}
+
+
+void RingClientUWP::MainPage::OnregistrationStateRegistered()
+{
+    showLoadingOverlay(false, false);
+}
diff --git a/MainPage.xaml.h b/MainPage.xaml.h
index 7252ac3..2a3acd5 100644
--- a/MainPage.xaml.h
+++ b/MainPage.xaml.h
@@ -77,5 +77,7 @@ private:
     void OnpressHangUpCall();
     void OnstateChange(Platform::String ^callId, CallStatus state, int code);
     void OncloseMessageTextPage();
+    void OnregistrationStateErrorGeneric(const std::string& accountId);
+    void OnregistrationStateRegistered();
 };
 }
diff --git a/RingD.cpp b/RingD.cpp
index 6ca978c..2e8e722 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -88,7 +88,8 @@ RingClientUWP::RingD::reloadAccountList()
                 accountUpdated(account);
             }
             else {
-                RingClientUWP::ViewModel::AccountsViewModel::instance->addRingAccount(alias, ringID, accountId, deviceId, upnpState);
+                if (!ringID.empty())
+                    RingClientUWP::ViewModel::AccountsViewModel::instance->addRingAccount(alias, ringID, accountId, deviceId, upnpState);
             }
         }
         else { /* SIP */
@@ -503,11 +504,22 @@ RingD::registerCallbacks()
                 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::High,
                 ref new DispatchedHandler([=]() {
                     reloadAccountList();
-                    if (editModeOn_) {
+                    // enleves ce qui suit et utilises des evenements.
+                    registrationStateRegistered();
+                    // mettre a jour le wizard
+                    /*if (editModeOn_) {
                         auto frame = dynamic_cast<Frame^>(Window::Current->Content);
                         dynamic_cast<RingClientUWP::MainPage^>(frame->Content)->showLoadingOverlay(false, false);
                         editModeOn_ = false;
-                    }
+                    }*/
+                }));
+            }
+            else if (state == DRing::Account::States::ERROR_GENERIC) {
+                CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::High,
+                ref new DispatchedHandler([=]() {
+                    reloadAccountList();
+                    registrationStateErrorGeneric(account_id);
+                    // ajoute cet event dans le wizard
                 }));
             }
         }),
@@ -893,6 +905,12 @@ RingD::dequeueTasks()
             deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::ARCHIVE_PIN, pin));
             deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::ARCHIVE_PASSWORD, password));
             DRing::addAccount(deviceDetails);
+
+            CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::High,
+            ref new DispatchedHandler([=]() {
+                auto frame = dynamic_cast<Frame^>(Window::Current->Content);
+                dynamic_cast<RingClientUWP::MainPage^>(frame->Content)->showLoadingOverlay(true, true);
+            }));
         }
         break;
         case Request::GetKnownDevices:
diff --git a/RingD.h b/RingD.h
index 1f648b4..b7db294 100644
--- a/RingD.h
+++ b/RingD.h
@@ -40,6 +40,8 @@ delegate void AccountUpdated(Account^ account);
 delegate void IncomingVideoMuted(String^ callId, bool state);
 delegate void RegisteredNameFound(LookupStatus status, const std::string& address, const std::string& name);
 delegate void FinishCaptureDeviceEnumeration();
+delegate void RegistrationStateErrorGeneric(const std::string& accountId);
+delegate void RegistrationStateRegistered();
 
 using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>;
 using namespace std::placeholders;
@@ -147,6 +149,8 @@ internal:
     event IncomingVideoMuted^ incomingVideoMuted;
     event RegisteredNameFound^ registeredNameFound;
     event FinishCaptureDeviceEnumeration^ finishCaptureDeviceEnumeration;
+    event RegistrationStateErrorGeneric^ registrationStateErrorGeneric;
+    event RegistrationStateRegistered^ registrationStateRegistered;
 
 private:
     /* sub classes */
diff --git a/SmartPanel.xaml b/SmartPanel.xaml
index d4bb6fe..e2e32de 100644
--- a/SmartPanel.xaml
+++ b/SmartPanel.xaml
@@ -475,13 +475,23 @@
                          Background="#FFE4F1F9"
                          ItemTemplate="{StaticResource AccountListItemsTemplate}"/>
                 </ScrollViewer>
-                <Button x:Name="_addAccountBtn_"
-                        Grid.Row="1"
-                        VerticalAlignment="Center"
-                        HorizontalAlignment="Center"
-                        Content="&#xE948;"
-                        Click="_addAccountBtn__Click"
-                        Style="{StaticResource ButtonStyle6}"/>
+                <StackPanel Orientation="Horizontal"
+                            Grid.Row="1">
+                    <!--Style="{StaticResource ButtonStyle6}"-->
+                    <Button x:Name="_addAccountBtn_"
+                            VerticalAlignment="Center"
+                            HorizontalAlignment="Center"
+                            Content="&#xE948;"
+                            Click="_addAccountBtn__Click"
+                            Style="{StaticResource ButtonStyle5}"/>
+                    <!--Style="{StaticResource ButtonStyle6}"-->
+                    <Button x:Name="_linkThisDeviceBtn_"
+                            VerticalAlignment="Center"
+                            HorizontalAlignment="Center"
+                            Content="&#xEBD2;"
+                            Click="_linkThisDeviceBtn__Click"
+                            Style="{StaticResource ButtonStyle5}"/>
+                </StackPanel>
             </Grid>
             <!-- account creation menu. -->
             <Grid x:Name="_accountCreationMenuGrid_"
@@ -695,6 +705,92 @@
                     </StackPanel>
                 </Grid>
             </Grid>
+            <!-- add account menu. -->
+            <Grid x:Name="_accountAddMenuGrid_"
+                  Visibility="Collapsed"
+                  Grid.Row="2"
+                  Background="LightBlue">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto"/>
+                    <RowDefinition Height="auto"/>
+                    <RowDefinition Height="30"/>
+                </Grid.RowDefinitions>
+                <StackPanel Orientation="Horizontal"
+                            Background="#FFE4F1F9"
+                            Padding="10"
+                                    Grid.Row="0">
+                    <Button x:Name="_step1button_"
+                            Click="_step1button__Click"
+                            Content="Step 1"/>
+                    <TextBlock Text=">"/>
+                    <Button x:Name="_step2button_"
+                            Click="_step2button__Click"
+                            Content="Step 2"/>
+                </StackPanel>
+                <!-- step 1. -->
+                <StackPanel x:Name="_step1Menu_"
+                                    Background="#FFE4F1F9"
+                                    Padding="10"
+                                    Grid.Row="1">
+                    <TextBlock Text="To link this device to a Ring account, you'll first need to generate a PIN from Ring on a device hosting the account."
+                                        TextWrapping="Wrap"
+                                        TextAlignment="Justify"/>
+                    <HyperlinkButton Content="Learn more"
+                                                Margin="0,0,0,10"
+                                                NavigateUri="http://ring.cx"/>
+                </StackPanel>
+                <!-- step 2. -->
+                <StackPanel x:Name="_step2Menu_"
+                                    Background="#FFE4F1F9"
+                                    Visibility="Collapsed"
+                                    Grid.Row="1">
+                    <TextBox  x:Name="_PINTextBox_"
+                                    Margin="10"
+                                    GotFocus="_PINTextBox__GotFocus"
+                                    PlaceholderText="Enter PIN"/>
+                    <PasswordBox x:Name="_ArchivePassword_"
+                                    Margin="10"
+                                    PlaceholderText="Enter your password"/>
+                    <TextBlock x:Name="_response_"
+                               Foreground="Red"
+                               HorizontalAlignment="Center"
+                               Text=""/>
+                </StackPanel>
+                <!-- buttons next step and yes/no to add the account. -->
+                <Grid Grid.Row="2">
+                    <StackPanel Orientation="Horizontal"
+                                        Padding="10,0"
+                                        HorizontalAlignment="Center">
+                        <Button x:Name="_nextstep_"
+                                        VerticalAlignment="Center"
+                                        HorizontalAlignment="Center"
+                                        Content="&#xE081;"
+                                        Click="_step2button__Click"
+                                        Style="{StaticResource ButtonStyle2}"/>
+                        <Button x:Name="_addAccountYes_"
+                                        VerticalAlignment="Center"
+                                        HorizontalAlignment="Center"
+                                        Visibility="Collapsed"
+                                        Content="&#xE081;"
+                                        Click="_addAccountYes__Click"
+                                        Style="{StaticResource ButtonStyle5}"/>
+                        <Button x:Name="_addAccountNo_"
+                                        VerticalAlignment="Center"
+                                        HorizontalAlignment="Center"
+                                        Visibility="Collapsed"
+                                        Content="&#xE106;"
+                                        Click="_addAccountNo__Click"
+                                        Style="{StaticResource ButtonStyle5}"/>
+                    </StackPanel>
+                </Grid>
+            </Grid>
+            <!--<StackPanel Orientation="Horizontal"
+                                Margin="0,20">
+                <TextBlock Style="{StaticResource TextSegoeStyle-20pt-black}"
+                                    Margin="0,0,10,0"
+                                    Text="&#xE8EC;"/>
+                <TextBlock Text="Alias"/>
+            </StackPanel>-->
             <!-- account edition menu. -->
             <Grid x:Name="_accountEditionGrid_"
                   Grid.Row="2"
@@ -740,7 +836,7 @@
                                                Style="{StaticResource TextSegoeStyle-20pt-red}"
                                                Text="&#xE10A;"/>
                         </Grid>
-                        <!-- upnp sub menu. -->
+                        <!-- edition sub menu. -->
                         <StackPanel x:Name="_ringStackEdition_">
                             <!-- register account on blockachain -->
                             <StackPanel Orientation="Horizontal"
diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp
index 4ca7e9c..9b51759 100644
--- a/SmartPanel.xaml.cpp
+++ b/SmartPanel.xaml.cpp
@@ -69,8 +69,10 @@ SmartPanel::SmartPanel()
             auto accountsListSize = dynamic_cast<Vector<AccountListItem^>^>(_accountsList_->ItemsSource)->Size;
             if (accountsListSize > index)
                 _accountsList_->SelectedIndex = index;
-            else
-                _accountsList_->SelectedIndex = 0;
+            else {
+                if (accountsListSize > 0)
+                    _accountsList_->SelectedIndex = 0;
+            }
         }
     });
     Configuration::UserPreferences::instance->loadProfileImage += ref new LoadProfileImage([this]() {
@@ -147,6 +149,8 @@ SmartPanel::SmartPanel()
     RingD::instance->finishCaptureDeviceEnumeration += ref new RingClientUWP::FinishCaptureDeviceEnumeration([this]() {
         populateVideoDeviceSettingsComboBox();
     });
+    RingD::instance->registrationStateErrorGeneric += ref new RingClientUWP::RegistrationStateErrorGeneric(this, &RingClientUWP::Views::SmartPanel::OnregistrationStateErrorGeneric);
+    RingD::instance->registrationStateRegistered += ref new RingClientUWP::RegistrationStateRegistered(this, &RingClientUWP::Views::SmartPanel::OnregistrationStateRegistered);
 }
 
 void
@@ -211,6 +215,7 @@ void RingClientUWP::Views::SmartPanel::_accountsMenuButton__Unchecked(Object^ se
     _accountsMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
     _accountCreationMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
     _accountEditionGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    _accountAddMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
 }
 
 void RingClientUWP::Views::SmartPanel::_settingsMenu__Checked(Object^ sender, RoutedEventArgs^ e)
@@ -733,6 +738,16 @@ void RingClientUWP::Views::SmartPanel::ringTxtBxPlaceHolderDelay(String^ placeHo
     }), delay);
 }
 
+void RingClientUWP::Views::SmartPanel::showLinkThisDeviceStep1()
+{
+    _step1Menu_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+    _step2Menu_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+
+    _nextstep_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+    _addAccountYes_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    _addAccountNo_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+}
+
 Object ^ RingClientUWP::Views::IncomingVisibility::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)
 {
     auto state = static_cast<CallStatus>(value);
@@ -1211,41 +1226,60 @@ void RingClientUWP::Views::SmartPanel::_usernameTextBoxEdition__KeyUp(Platform::
 
 void RingClientUWP::Views::SmartPanel::OnregisteredNameFound(RingClientUWP::LookupStatus status, const std::string& address, const std::string& name)
 {
-    if (_ringTxtBx_->Text->IsEmpty()) // if true, we consider we did the lookup for a new account
-        switch (status)
-        {
-        case LookupStatus::SUCCESS:
-            _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+    if (_ringTxtBx_->Text->IsEmpty()) { // if true, we consider we did the lookup for a new account
+        /* note : this code do both check for edit and creation menu. It doesn't affect the use and it's easier to
+           implement. */
+        auto currentNameEdition = Utils::toString(_usernameTextBoxEdition_->Text);
+        if (currentNameEdition == name) {
+            switch (status)
+            {
+            case LookupStatus::SUCCESS:
+                _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                break;
+            case LookupStatus::INVALID_NAME:
+                _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                break;
+            case LookupStatus::NOT_FOUND:
+                _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                break;
+            case LookupStatus::ERRORR:
+                _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                break;
+            }
+            checkStateEditionMenu();
+            return;
+        }
 
-            //_registerOnBlockchainEdition_->IsEnabled = false;
-            break;
-        case LookupStatus::INVALID_NAME:
-            _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            //_registerOnBlockchainEdition_->IsEnabled = false;
-            break;
-        case LookupStatus::NOT_FOUND:
-            _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            //_registerOnBlockchainEdition_->IsEnabled = true;
-            break;
-        case LookupStatus::ERRORR:
-            _usernameValidEdition_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameInvalidEdition_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
-            _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
-            //_registerOnBlockchainEdition_->IsEnabled = false;
-            break;
+        auto currentNameCreation = Utils::toString(_usernameTextBox_->Text);
+        if (currentNameCreation == name) {
+            switch (status)
+            {
+            case LookupStatus::SUCCESS:
+                _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                break;
+            case LookupStatus::INVALID_NAME:
+                _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                break;
+            case LookupStatus::NOT_FOUND:
+                _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                break;
+            case LookupStatus::ERRORR:
+                _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+                _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+                break;
+            }
+            checkStateAddAccountMenu();
+            return;
         }
-    else // if false, we consider we are looking for a registered user
-    {
+
+    } else {// if false, we consider we are looking for a registered user
         switch (status) {
         case LookupStatus::SUCCESS:
             ContactsViewModel::instance->addNewContact(Utils::toPlatformString(name), Utils::toPlatformString(address));
@@ -1274,10 +1308,7 @@ void RingClientUWP::Views::SmartPanel::OnregisteredNameFound(RingClientUWP::Look
         }
 
         _smartList_->SelectedItem = nullptr;
-
     }
-
-    checkStateAddAccountMenu();
 }
 
 
@@ -1340,6 +1371,8 @@ void RingClientUWP::Views::SmartPanel::_usernameTextBox__KeyUp(Platform::Object^
 
     _usernameValid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
     _usernameInvalid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+
+
 }
 
 
@@ -1537,3 +1570,68 @@ void RingClientUWP::Views::SmartPanel::_ringTxtBx__KeyUp(Platform::Object^ sende
     }
 
 }
+
+
+void RingClientUWP::Views::SmartPanel::_linkThisDeviceBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _accountsMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    _accountAddMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+
+    showLinkThisDeviceStep1();
+}
+
+
+void RingClientUWP::Views::SmartPanel::_step2button__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _step1Menu_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    _step2Menu_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+
+    _nextstep_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+    _addAccountYes_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+    _addAccountNo_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+
+    _PINTextBox_->Text = "";
+    _ArchivePassword_->Password = "";
+    _response_->Text = "";
+}
+
+
+void RingClientUWP::Views::SmartPanel::_step1button__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    showLinkThisDeviceStep1();
+}
+
+
+void RingClientUWP::Views::SmartPanel::_addAccountNo__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _accountsMenuButton_->IsChecked = false;
+    _accountsMenuButton__Unchecked(nullptr, nullptr);
+}
+
+
+void RingClientUWP::Views::SmartPanel::_addAccountYes__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this]() {
+        RingD::instance->registerThisDevice(_PINTextBox_->Text, _ArchivePassword_->Password);
+        _ArchivePassword_->Password = "";
+        _PINTextBox_->Text = "";
+    }));
+}
+
+
+void RingClientUWP::Views::SmartPanel::OnregistrationStateErrorGeneric(const std::string& accountId)
+{
+    _response_->Text = "Credentials error or PIN expired.";
+}
+
+
+void RingClientUWP::Views::SmartPanel::_PINTextBox__GotFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _response_->Text = "";
+}
+
+
+void RingClientUWP::Views::SmartPanel::OnregistrationStateRegistered()
+{
+    _addAccountNo__Click(nullptr, nullptr);
+}
diff --git a/SmartPanel.xaml.h b/SmartPanel.xaml.h
index ca6f1cd..18981b1 100644
--- a/SmartPanel.xaml.h
+++ b/SmartPanel.xaml.h
@@ -129,6 +129,7 @@ private:
     void checkStateAddAccountMenu();
     void checkStateEditionMenu();
     void ringTxtBxPlaceHolderDelay(String^ placeHolderText, int delayInMilliSeconds);
+    void showLinkThisDeviceStep1();
 
     /* members */
     void _devicesMenuButton__Unchecked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
@@ -161,6 +162,14 @@ private:
     void _deleteAccountEdition__Toggled(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
     void _RegisterStateEdition__Toggled(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
     void _ringTxtBx__KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e);
+    void _linkThisDeviceBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _step2button__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _step1button__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _addAccountNo__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _addAccountYes__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void OnregistrationStateErrorGeneric(const std::string& accountId);
+    void _PINTextBox__GotFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void OnregistrationStateRegistered();
 };
 }
 }
diff --git a/Wizard.xaml b/Wizard.xaml
index 2f1d1f3..bb20ceb 100644
--- a/Wizard.xaml
+++ b/Wizard.xaml
@@ -217,7 +217,7 @@
                                         Click="_step2button__Click"
                                         Content="Step 2"/>
                             </StackPanel>
-                            <!-- add account menu. -->
+                            <!-- step 1. -->
                             <StackPanel x:Name="_step1Menu_"
                                         Background="#FFE4F1F9"
                                         Padding="10"
@@ -229,17 +229,22 @@
                                                  Margin="0,0,0,10"
                                                  NavigateUri="http://ring.cx"/>
                             </StackPanel>
-                            <!-- add account menu. -->
+                            <!-- step 2. -->
                             <StackPanel x:Name="_step2Menu_"
                                         Background="#FFE4F1F9"
                                         Visibility="Collapsed"
                                         Grid.Row="1">
                                 <TextBox  x:Name="_PINTextBox_"
                                       Margin="10"
+                                      GotFocus="_PINTextBox__GotFocus"
                                       PlaceholderText="Enter PIN"/>
                                 <PasswordBox x:Name="_ArchivePassword_"
                                       Margin="10"
                                       PlaceholderText="Enter your password"/>
+                                <TextBlock x:Name="_response_"
+                                           Foreground="Red"
+                                           HorizontalAlignment="Center"
+                                           Text=""/>
                             </StackPanel>
                             <!-- buttons next step and yes/no to add the account. -->
                             <Grid Grid.Row="2">
diff --git a/Wizard.xaml.cpp b/Wizard.xaml.cpp
index 7209898..04f0861 100644
--- a/Wizard.xaml.cpp
+++ b/Wizard.xaml.cpp
@@ -30,6 +30,7 @@ Wizard::Wizard()
     InitializeComponent();
     /* connect to delegates */
     RingD::instance->registeredNameFound += ref new RingClientUWP::RegisteredNameFound(this, &RingClientUWP::Views::Wizard::OnregisteredNameFound);
+    RingD::instance->registrationStateErrorGeneric += ref new RingClientUWP::RegistrationStateErrorGeneric(this, &RingClientUWP::Views::Wizard::OnregistrationStateErrorGeneric);
 }
 
 void RingClientUWP::Views::Wizard::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs ^ e)
@@ -295,3 +296,15 @@ void RingClientUWP::Views::Wizard::OnregisteredNameFound(LookupStatus status, co
     checkState();
 }
 
+
+
+void RingClientUWP::Views::Wizard::OnregistrationStateErrorGeneric(const std::string &accountId)
+{
+    _response_->Text = "Credentials error or PIN expired.";
+}
+
+
+void RingClientUWP::Views::Wizard::_PINTextBox__GotFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _response_->Text = "";
+}
diff --git a/Wizard.xaml.h b/Wizard.xaml.h
index 5808a6f..2c97f7e 100644
--- a/Wizard.xaml.h
+++ b/Wizard.xaml.h
@@ -38,6 +38,8 @@ private:
     bool isPublic = true;
     bool isUsernameValid; // available
     bool isFullNameValid;
+    void OnregistrationStateErrorGeneric(const std::string &accountId);
+    void _PINTextBox__GotFocus(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
 };
 
 }
-- 
GitLab