From e4eb513491378891edf45bddabfc5cf0583ea2c2 Mon Sep 17 00:00:00 2001
From: Nicolas Jager <nicolas.jager@savoirfairelinux.com>
Date: Tue, 4 Oct 2016 14:25:15 -0400
Subject: [PATCH] Wizard : add multi device support

Change-Id: I501120b7a5e1a2b8e90d7a5c8dd8a18a0fb3ed7c
Tuleap: #1207
---
 LoadingPage.xaml.cpp |  6 ++----
 Package.appxmanifest |  2 +-
 RingD.cpp            | 32 +++++++++++++++++++++++++++++---
 RingD.h              | 20 ++++++++++++++++++--
 SmartPanel.xaml      | 33 +++++++++++++++++++++++++++++++++
 SmartPanel.xaml.cpp  | 17 +++++++++++++++++
 SmartPanel.xaml.h    |  3 +++
 Wizard.xaml          |  4 +++-
 Wizard.xaml.cpp      | 25 ++++++++++++++++++-------
 Wizard.xaml.h        |  1 +
 10 files changed, 125 insertions(+), 18 deletions(-)

diff --git a/LoadingPage.xaml.cpp b/LoadingPage.xaml.cpp
index ac0b6cf..df8bf3d 100644
--- a/LoadingPage.xaml.cpp
+++ b/LoadingPage.xaml.cpp
@@ -52,14 +52,12 @@ LoadingPage::LoadingPage()
     .then([this](bool config_exists)
     {
         if (config_exists) {
-            RingD::instance->hasConfig = true;
-            this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this] () {
+            this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this] () {
                 this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(MainPage::typeid));
             }));
         }
         else {
-            RingD::instance->hasConfig = false;
-            this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this] () {
+            this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this] () {
                 this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Wizard::typeid));
             }));
         }
diff --git a/Package.appxmanifest b/Package.appxmanifest
index e096e06..9cece41 100644
--- a/Package.appxmanifest
+++ b/Package.appxmanifest
@@ -15,7 +15,7 @@
   </Resources>
   <Applications>
     <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="RingClientUWP.App">
-      <uap:VisualElements DisplayName="ring-client-uwp" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="ring-client-uwp" BackgroundColor="transparent">
+      <uap:VisualElements DisplayName="ring-client-uwp-md" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="ring-client-uwp" BackgroundColor="transparent">
         <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
         </uap:DefaultTile>
         <uap:SplashScreen Image="Assets\SplashScreen.png" />
diff --git a/RingD.cpp b/RingD.cpp
index 58ccfbe..0e6249f 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -425,16 +425,29 @@ RingClientUWP::RingD::startDaemon()
             return;
         }
         else {
-            if (!hasConfig) {
+            switch (_startingStatus) {
+            case StartingStatus::REGISTERING_ON_THIS_PC:
+            {
                 tasksList_.push(ref new RingD::Task(Request::AddRingAccount));
                 tasksList_.push(ref new RingD::Task(Request::AddSIPAccount));
+                break;
             }
-            else {
-                CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::High,
+            case StartingStatus::REGISTERING_THIS_DEVICE:
+            {
+                tasksList_.push(ref new RingD::Task(Request::RegisterDevice, _pin, _password));
+                break;
+            }
+            case StartingStatus::NORMAL:
+            default:
+            {
+                CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Normal,
                 ref new DispatchedHandler([=]() {
                     reloadAccountList();
                 }));
+                break;
             }
+            }
+
             while (true) {
                 DRing::pollEvents();
                 dequeueTasks();
@@ -498,6 +511,19 @@ RingD::dequeueTasks()
             DRing::hangUp(Utils::toString(callId));
         }
         break;
+        case Request::RegisterDevice:
+        {
+            auto pin = Utils::toString(_pin);
+            auto password = Utils::toString(_password);
+
+            std::map<std::string, std::string> deviceDetails;
+            deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::TYPE, "RING"));
+            //deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::UPNP_ENABLED, "true"));
+            //deviceDetails.insert(std::make_pair(DRing::Account::ConfProperties::ALIAS, "MonSuperUsername"));
+            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);
+        }
         default:
             break;
         }
diff --git a/RingD.h b/RingD.h
index c1eed29..b8177bc 100644
--- a/RingD.h
+++ b/RingD.h
@@ -21,6 +21,10 @@ using namespace concurrency;
 
 namespace RingClientUWP
 {
+// its ok to keep this enum here and to use it with the wizard, because in pch.h headers are a-z sorted,
+// but it would be much more consistent to move this enum in globals.h when merged
+
+public enum class StartingStatus { NORMAL, REGISTERING_ON_THIS_PC, REGISTERING_THIS_DEVICE };
 
 /* delegate */
 delegate void IncomingCall(String^ accountId, String^ callId, String^ from);
@@ -63,6 +67,9 @@ internal: // why this property has to be internal and not public ?
         }
     }
 
+    property StartingStatus _startingStatus;
+    property String^ _pin;
+    property String^ _password;
 
 internal:
     /* functions */
@@ -80,7 +87,7 @@ internal:
     void hangUpCall2(String^ callId);
 
     /* TODO : move members */
-    bool hasConfig;
+    ///bool hasConfig; // replaced by startingStatus
     std::string accountName;
 
     /* events */
@@ -98,7 +105,8 @@ private:
         RefuseIncommingCall,
         AcceptIncommingCall,
         CancelOutGoingCall,
-        HangUpCall
+        HangUpCall,
+        RegisterDevice
     };
 
 
@@ -114,9 +122,16 @@ private:
             request = r;
             _callId = c;
         }
+        Task(Request r, String^ p, String^ P) {
+            request = r;
+            _pin = p;
+            _password = P;
+        }
     public:
         property Request request;
         property String^ _callId;
+        property String^ _pin;
+        property String^ _password;
     };
 
     /* functions */
@@ -128,5 +143,6 @@ private:
     std::string localFolder_;
     bool daemonRunning_ = false;
     std::queue<Task^> tasksList_;
+    StartingStatus startingStatus_ = StartingStatus::NORMAL;
 };
 }
\ No newline at end of file
diff --git a/SmartPanel.xaml b/SmartPanel.xaml
index 4bda00e..f62e36d 100644
--- a/SmartPanel.xaml
+++ b/SmartPanel.xaml
@@ -389,6 +389,11 @@
                                       Checked="_shareMenuButton__Checked"
                                       Unchecked="_shareMenuButton__Unchecked"
                                       Style="{StaticResource ToggleButtonStyle1}"/>
+                        <ToggleButton x:Name="_devicesMenuButton_"
+                                      VerticalAlignment="Bottom"
+                                      Content="devices;"
+                                      Checked="_devicesMenuButton__Checked"
+                                      Unchecked="_devicesMenuButton__Unchecked"/>
                     </StackPanel>
                 </StackPanel>
                 <ToggleButton x:Name="_settingsTBtn_"
@@ -520,6 +525,34 @@
                              Grid.Row="2"/>
                 </Grid>
             </Grid>
+            <!-- devices menu. -->
+            <Grid x:Name="_devicesMenuGrid_"
+                  Grid.Row="2"
+                  Visibility="Collapsed"
+                  Background="LightBlue">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="*"/>
+                    <RowDefinition Height="30"/>
+                </Grid.RowDefinitions>
+                <Grid Background="#FFE4F1F9">
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="auto"/>
+                        <RowDefinition Height="*"/>
+                        <RowDefinition Height="auto"/>
+                        <RowDefinition Height="auto"/>
+                    </Grid.RowDefinitions>
+                    <TextBlock Text="devices:"
+                               Grid.Row="0"
+                               HorizontalAlignment="Center"/>
+                </Grid>
+                <Button x:Name="_addDevice_"
+                        Grid.Row="1"
+                        VerticalAlignment="Center"
+                        HorizontalAlignment="Center"
+                        Content="&#xE948;"
+                        Click="_addDevice__Click"
+                        Style="{StaticResource ButtonStyle6}"/>
+            </Grid>
         </Grid>
         <!-- smartList and settings. -->
         <Grid Grid.Row="1">
diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp
index b91a2ac..f596aa2 100644
--- a/SmartPanel.xaml.cpp
+++ b/SmartPanel.xaml.cpp
@@ -463,3 +463,20 @@ Object ^ RingClientUWP::Views::NewMessageBubleNotification::ConvertBack(Object ^
 
 RingClientUWP::Views::NewMessageBubleNotification::NewMessageBubleNotification()
 {}
+
+void RingClientUWP::Views::SmartPanel::_devicesMenuButton__Unchecked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _devicesMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
+}
+
+
+void RingClientUWP::Views::SmartPanel::_devicesMenuButton__Checked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    _devicesMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Visible;
+}
+
+
+void RingClientUWP::Views::SmartPanel::_addDevice__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+
+}
diff --git a/SmartPanel.xaml.h b/SmartPanel.xaml.h
index c017617..64567ad 100644
--- a/SmartPanel.xaml.h
+++ b/SmartPanel.xaml.h
@@ -95,6 +95,9 @@ private:
     void _contactItem__PointerReleased(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e);
 
     /* members */
+    void _devicesMenuButton__Unchecked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _devicesMenuButton__Checked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _addDevice__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
 };
 }
 }
\ No newline at end of file
diff --git a/Wizard.xaml b/Wizard.xaml
index 599ae1c..0b11d97 100644
--- a/Wizard.xaml
+++ b/Wizard.xaml
@@ -115,7 +115,8 @@
                         <TextBox  x:Name="_PINTextBox_"
                                   Margin="10"
                                   PlaceholderText="Enter PIN"/>
-                        <PasswordBox Margin="10"
+                        <PasswordBox x:Name="_ArchivePassword_"
+                                Margin="10"
                                  PlaceholderText="Enter your password"/>
                     </StackPanel>
                     <!-- buttons yes/no to add the account. -->
@@ -127,6 +128,7 @@
                                 VerticalAlignment="Center"
                                 HorizontalAlignment="Center"
                                 Content="&#xE081;"
+                                Click="_addAccountYes__Click"
                                 Style="{StaticResource ButtonStyle2}"/>
                         </StackPanel>
                     </Grid>
diff --git a/Wizard.xaml.cpp b/Wizard.xaml.cpp
index 13c9556..a643a78 100644
--- a/Wizard.xaml.cpp
+++ b/Wizard.xaml.cpp
@@ -36,7 +36,7 @@ Wizard::_createAccountYes__Click(Object^ sender, RoutedEventArgs^ e)
         alias = "windows user";
     std::wstring wstr(alias->Begin());
     std::string str(wstr.begin(), wstr.end());
-    RingD::instance->hasConfig = false;
+    RingD::instance->_startingStatus = StartingStatus::REGISTERING_ON_THIS_PC;
     RingD::instance->accountName = std::string(wstr.begin(), wstr.end());
     this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this] () {
         this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(RingClientUWP::MainPage::typeid));
@@ -75,7 +75,7 @@ Wizard::_avatarWebcamCaptureBtn__Click(Platform::Object^ sender, Windows::UI::Xa
     cameraCaptureUI->PhotoSettings->CroppedSizeInPixels = Size(100, 100);
 
     create_task(cameraCaptureUI->CaptureFileAsync(CameraCaptureUIMode::Photo))
-        .then([this](StorageFile^ photoFile)
+    .then([this](StorageFile^ photoFile)
     {
         if (photoFile != nullptr) {
             // maybe it would be possible to move some logics to the style sheet
@@ -92,13 +92,13 @@ Wizard::_avatarWebcamCaptureBtn__Click(Platform::Object^ sender, Windows::UI::Xa
             StorageFolder^ localfolder = ApplicationData::Current->LocalFolder;
             String^ profilefolder = ".profile";
             create_task(localfolder->CreateFolderAsync(profilefolder,
-                Windows::Storage::CreationCollisionOption::OpenIfExists))
-                .then([=](StorageFolder^ copytofolder){
+                        Windows::Storage::CreationCollisionOption::OpenIfExists))
+            .then([=](StorageFolder^ copytofolder) {
                 try {
                     create_task(photoFile->CopyAsync(copytofolder))
-                        .then([=](StorageFile^ copiedfile){
+                    .then([=](StorageFile^ copiedfile) {
                         copiedfile->RenameAsync("profile_image.png",
-                            Windows::Storage::NameCollisionOption::ReplaceExisting);
+                                                Windows::Storage::NameCollisionOption::ReplaceExisting);
                     });
                 }
                 catch (Exception^ e) {
@@ -114,4 +114,15 @@ Wizard::_avatarWebcamCaptureBtn__Click(Platform::Object^ sender, Windows::UI::Xa
         }
     });
 
-}
\ No newline at end of file
+}
+
+void RingClientUWP::Views::Wizard::_addAccountYes__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
+{
+    RingD::instance->_pin = _PINTextBox_->Text;
+    RingD::instance->_password = _ArchivePassword_->Password;
+    RingD::instance->_startingStatus = StartingStatus::REGISTERING_THIS_DEVICE;
+
+    this->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this]() {
+        this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(RingClientUWP::MainPage::typeid));
+    }));
+}
diff --git a/Wizard.xaml.h b/Wizard.xaml.h
index 7c146a0..28cbcd6 100644
--- a/Wizard.xaml.h
+++ b/Wizard.xaml.h
@@ -16,6 +16,7 @@ private:
     void _showCreateAccountMenuBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
     void _showAddAccountMenuBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
     void _avatarWebcamCaptureBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+    void _addAccountYes__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
 };
 
 }
-- 
GitLab