smartpanel : refactoring

Change-Id: Iea01dd8242270e1c080cd95030da4d211638d993
Tuleap: #1202
diff --git a/Call.cpp b/Call.cpp
index b756033..6cc2fe3 100644
--- a/Call.cpp
+++ b/Call.cpp
@@ -35,17 +35,10 @@
 

     isOutGoing = false; // by default, we consider the call incomming, REFACTO : add this to the constructor params...

 

-    this->state = "incoming call";

+    this->state = CallStatus::NONE;

     this->code = -1;

 }

 

-void RingClientUWP::Call::stateChange(String ^ state, int code)

-{

-    this->state = state;

-    PropertyChanged(this, ref new PropertyChangedEventArgs("state"));

-    this->code = code;

-}

-

 void

 Call::NotifyPropertyChanged(String^ propertyName)

 {

diff --git a/Call.h b/Call.h
index fb5be0b..dfebe21 100644
--- a/Call.h
+++ b/Call.h
@@ -21,12 +21,15 @@
 

 namespace RingClientUWP

 {

+/* enumerations. */

+public enum class CallStatus { NONE, INCOMING_RINGING, OUTGOING_RINGING, SEARCHING, IN_PROGRESS, ENDED };

+

 public ref class Call sealed : public INotifyPropertyChanged

 {

 public:

+

     /* functions */

     Call(String^ accountId, String^ callId, String^ from);

-    void stateChange(String^ state, int code);

 

     /* properties */

     virtual event PropertyChangedEventHandler^ PropertyChanged;

@@ -34,7 +37,15 @@
     property String^ accountId;

     property String^ callId;

     property String^ from;

-    property String^ state;

+    property CallStatus state {

+        CallStatus get() {

+            return state_;

+        }

+        void set(CallStatus value) {

+            state_ = value;

+            PropertyChanged(this, ref new PropertyChangedEventArgs("state"));

+        }

+    }

     property bool isOutGoing;

     property int code;

 

@@ -49,6 +60,9 @@
     void accept();

     void cancel();

 

+private:

+    CallStatus state_;

+

 };

 }

 

diff --git a/CallsViewModel.cpp b/CallsViewModel.cpp
index b714790..07e9019 100644
--- a/CallsViewModel.cpp
+++ b/CallsViewModel.cpp
@@ -34,32 +34,10 @@
     RingD::instance->incomingCall += ref new RingClientUWP::IncomingCall([&](

     String^ accountId, String^ callId, String^ from) {

         auto call = addNewCall(accountId, callId, from);

-        // REFACTO : add if call == nullptr

-        callRecieved(call);

+        if (call)

+            callRecieved(call);

     });

-

-    RingD::instance->stateChange += ref new RingClientUWP::StateChange([&](

-    String^ callId, String^ state, int code) {

-        for each (auto call in CallsList_) {

-            if (call->callId == callId) {

-                if (state == "OVER") {

-                    delete call;

-                    call->stateChange("", code);

-                    callEnded();

-                    callStatusUpdated(call); // used ?

-                    RingD::instance->hangUpCall(call);

-                    return;

-                }

-                else if (state == "CURRENT") {

-                    callStarted();

-                }

-                call->stateChange(state, code);

-                callStatusUpdated(call); // same...

-                return;

-            }

-        }

-        WNG_("Call not found");

-    });

+    RingD::instance->stateChange += ref new RingClientUWP::StateChange(this, &RingClientUWP::ViewModel::CallsViewModel::OnstateChange);

 }

 

 Call^

@@ -87,3 +65,20 @@
 

     return nullptr;

 }

+

+

+void RingClientUWP::ViewModel::CallsViewModel::OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code)

+{

+    auto call = findCall(callId);

+

+    if (!call)

+        return;

+

+    switch (state)

+    {

+    case CallStatus::ENDED:

+        RingD::instance->hangUpCall(call);

+    default:

+        break;

+    }

+}

diff --git a/CallsViewModel.h b/CallsViewModel.h
index 4938249..24ddbb0 100644
--- a/CallsViewModel.h
+++ b/CallsViewModel.h
@@ -66,6 +66,7 @@
     CallsViewModel(); // singleton

     Vector<Call^>^ CallsList_; // refacto : change C to c

 

+    void OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code);

 };

 }

 }

diff --git a/Contact.cpp b/Contact.cpp
index fd463af..155a7ff 100644
--- a/Contact.cpp
+++ b/Contact.cpp
@@ -65,28 +65,6 @@
         notificationNewMessage = Windows::UI::Xaml::Visibility::Visible;

         PropertyChanged(this, ref new PropertyChangedEventArgs("unreadMessages"));

     }

-

-    /* connect to delegate */

-    ContactsViewModel::instance->notifyNewConversationMessage += ref new NotifyNewConversationMessage([&] (

-    bool isContactNotSelected) {

-        if (isContactNotSelected)

-            PropertyChanged(this, ref new PropertyChangedEventArgs("unreadMessages"));

-    });

-    ContactsViewModel::instance->newContactSelected += ref new RingClientUWP::NewContactSelected([&]() {

-        if (ContactsViewModel::instance->selectedContact == this) {

-            PropertyChanged(this, ref new PropertyChangedEventArgs("unreadMessages"));

-            notificationNewMessage = Windows::UI::Xaml::Visibility::Collapsed;

-            unreadMessages_ = 0;

-            ContactsViewModel::instance->saveContactsToFile();

-        }

-    });

-}

-

-void

-Contact::addNotifyNewConversationMessage()

-{

-    notificationNewMessage = Windows::UI::Xaml::Visibility::Visible;

-    unreadMessages_++;

 }

 

 void

@@ -169,4 +147,8 @@
             file.close();

         }

     }

-}
\ No newline at end of file
+}

+

+

+

+

diff --git a/Contact.h b/Contact.h
index a88d648..d2cdf28 100644
--- a/Contact.h
+++ b/Contact.h
@@ -64,23 +64,16 @@
             PropertyChanged(this, ref new PropertyChangedEventArgs("notificationNewMessage"));

         }

     }

-    property String^ unreadMessages

+    property uint32 _unreadMessages

     {

-        String^ get()

+        uint32 get()

         {

-            return unreadMessages_.ToString();

+            return unreadMessages_;

         }

-    }

-    property Call^ _call

-    {

-        Call^ get()

+        void set(uint32 value)

         {

-            return call_;

-        }

-        void set(Call^ call)

-        {

-            call_ = call;

-            PropertyChanged(this, ref new PropertyChangedEventArgs("_call"));

+            unreadMessages_ = value;

+            PropertyChanged(this, ref new PropertyChangedEventArgs("_unreadMessages"));

         }

     }

     property Windows::UI::Xaml::GridLength _contactBarHeight

@@ -100,7 +93,6 @@
     void        saveConversationToFile();

     String^     StringifyConversation();

     void        DestringifyConversation(String^ data);

-    void        addNotifyNewConversationMessage();

 

 protected:

     void NotifyPropertyChanged(String^ propertyName);

@@ -110,7 +102,6 @@
     Visibility notificationNewMessage_;

     unsigned int unreadMessages_;

     Windows::UI::Xaml::GridLength contactBarHeight_ = 0;

-    Call^ call_;

 };

 }

 

diff --git a/ContactsViewModel.cpp b/ContactsViewModel.cpp
index e49ea1c..cb98f58 100644
--- a/ContactsViewModel.cpp
+++ b/ContactsViewModel.cpp
@@ -39,13 +39,13 @@
 

     /* connect delegates. */

     RingD::instance->incomingAccountMessage += ref new IncomingAccountMessage([&](String^ accountId,

-    String^ from, String^ payload) {

-        auto contact = findContactByName(from);

+    String^ fromRingId, String^ payload) {

+        auto contact = findContactByName(fromRingId);

 

         if (contact == nullptr)

-            contact = addNewContact(from, from); // contact checked inside addNewContact.

+            contact = addNewContact(fromRingId, fromRingId); // contact checked inside addNewContact.

 

-        bool isNotSelected = (contact != ContactsViewModel::instance->selectedContact) ? true : false;

+        auto item = SmartPanelItemsViewModel::instance->_selectedItem;

 

         if (contact == nullptr) {

             ERR_("contact not handled!");

@@ -57,15 +57,13 @@
         /* save contacts conversation to disk */

         contact->saveConversationToFile();

 

-        if (contact->ringID_ == from) {

-            // increment contact's unread message count

-            if (isNotSelected) {

-                contact->addNotifyNewConversationMessage();

-                // save to disk

-                saveContactsToFile();

-            }

-            // update the xaml for all contacts

-            notifyNewConversationMessage(isNotSelected);

+

+        auto selectedContact = (item) ? item->_contact : nullptr;

+

+        if (contact->ringID_ == fromRingId && contact != selectedContact) {

+            contact->_unreadMessages++;

+            /* saveContactsToFile used to save the notification */

+            saveContactsToFile();

         }

     });

 }

diff --git a/ContactsViewModel.h b/ContactsViewModel.h
index 8350f6d..ab7e56d 100644
--- a/ContactsViewModel.h
+++ b/ContactsViewModel.h
@@ -26,11 +26,6 @@
 {

 

 /* delegates */

-delegate void NewContactSelected();

-delegate void NoContactSelected();

-delegate void ScreenConversationMessage(String^ accountId, String^ from, String^ payload);

-delegate void NotifyNewConversationMessage(bool isContactNotSelected);

-delegate void ShowContactBar();

 delegate void ContactAdded(Contact^);

 

 namespace ViewModel {

@@ -56,23 +51,6 @@
     void        Destringify(String^ data);

 

     /* properties */

-    property Contact^ selectedContact

-    {

-        Contact^ get()

-        {

-            return currentItem_;

-        }

-        void set(Contact^ value)

-        {

-            oldItem_ = currentItem_;

-            currentItem_ = value;

-            if (value)

-                newContactSelected();

-            else

-                noContactSelected();

-        }

-    }

-

     property Vector<Contact^>^ contactsList

     {

         Vector<Contact^>^ get()

@@ -82,11 +60,6 @@
     }

 

     /* events */

-    event NewContactSelected^ newContactSelected;

-    event NoContactSelected^ noContactSelected;

-    event ScreenConversationMessage^ screenConversationMessage;

-    event NotifyNewConversationMessage^ notifyNewConversationMessage;

-    event ShowContactBar^ showContactBar;

     event ContactAdded^ contactAdded;

 

 private:

diff --git a/MainPage.xaml.cpp b/MainPage.xaml.cpp
index 67ec540..191ae3b 100644
--- a/MainPage.xaml.cpp
+++ b/MainPage.xaml.cpp
@@ -60,36 +60,13 @@
     _messageTextFrame_->Navigate(TypeName(RingClientUWP::Views::MessageTextPage::typeid));

 

     /* connect to delegates */

-    ContactsViewModel::instance->newContactSelected += ref new NewContactSelected([&]() {

-        Contact^ selectedContact = ContactsViewModel::instance->selectedContact;

-        auto call = selectedContact?

-                    SmartPanelItemsViewModel::instance->findItem(selectedContact)->_call:

-                    nullptr;

-        if (call != nullptr) {

-            if (call->state == "CURRENT")

-                showFrame(_videoFrame_);

-            else

-                showFrame(_messageTextFrame_);

-        }

-        else {

-            showFrame(_messageTextFrame_);

-        }

-    });

-    ContactsViewModel::instance->noContactSelected += ref new NoContactSelected([&]() {

-        showFrame(_welcomeFrame_);

-    });

-    CallsViewModel::instance->callStarted += ref new CallStarted([&]() {

-        showFrame(_videoFrame_);

-    });

-    CallsViewModel::instance->callEnded += ref new CallEnded([&]() {

-        auto contact = ContactsViewModel::instance->selectedContact;

-

-        if(contact)

-            showFrame(_messageTextFrame_);

-        else

-            showFrame(_welcomeFrame_);

-

-    });

+    RingD::instance->stateChange += ref new RingClientUWP::StateChange(this, &RingClientUWP::MainPage::OnstateChange);

+    auto smartPanel = dynamic_cast<SmartPanel^>(_smartPanel_->Content);

+    smartPanel->summonMessageTextPage += ref new RingClientUWP::SummonMessageTextPage(this, &RingClientUWP::MainPage::OnsummonMessageTextPage);

+    smartPanel->summonWelcomePage += ref new RingClientUWP::SummonWelcomePage(this, &RingClientUWP::MainPage::OnsummonWelcomePage);

+    smartPanel->summonVideoPage += ref new RingClientUWP::SummonVideoPage(this, &RingClientUWP::MainPage::OnsummonVideoPage);

+    auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);

+    videoPage->pressHangUpCall += ref new RingClientUWP::PressHangUpCall(this, &RingClientUWP::MainPage::OnpressHangUpCall);

 

     DisplayInformation^ displayInformation = DisplayInformation::GetForCurrentView();

     dpiChangedtoken = (displayInformation->DpiChanged += ref new TypedEventHandler<DisplayInformation^,

@@ -132,7 +109,6 @@
         dynamic_cast<VideoPage^>(_videoFrame_->Content)->updatePageContent();

     } else if (frame == _messageTextFrame_) {

         _navGrid_->SetRow(_messageTextFrame_, 1);

-        dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content)->updatePageContent();

     }

 }

 

@@ -227,4 +203,60 @@
 RingClientUWP::MainPage::hideLoadingOverlay()

 {

     _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;

-}
\ No newline at end of file
+}

+

+void RingClientUWP::MainPage::OnsummonMessageTextPage()

+{

+    auto messageTextPage = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);

+    messageTextPage->updatePageContent();

+    showFrame(_messageTextFrame_);

+

+}

+

+

+void RingClientUWP::MainPage::OnsummonWelcomePage()

+{

+    showFrame(_welcomeFrame_);

+}

+

+

+void RingClientUWP::MainPage::OnsummonVideoPage()

+{

+    auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);

+    videoPage->updatePageContent();

+    showFrame(_videoFrame_);

+}

+

+

+void RingClientUWP::MainPage::OnpressHangUpCall()

+{

+    OnsummonMessageTextPage();

+}

+

+

+

+void RingClientUWP::MainPage::OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code)

+{

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+

+    switch (state) {

+    /* send the user to the peer's message text page */

+    case CallStatus::ENDED:

+    {

+        if (item)

+            OnsummonMessageTextPage();

+        break;

+    }

+    /* if the state changes to IN_PROGRESS for any peer, show the video page.

+       nb : the peer is currently selected from the SmartPannel. */

+    case CallStatus::IN_PROGRESS:

+    {

+        if (item)

+            OnsummonVideoPage();

+        break;

+    }

+    default:

+        break;

+    }

+

+}

diff --git a/MainPage.xaml.h b/MainPage.xaml.h
index aa76667..d97fd59 100644
--- a/MainPage.xaml.h
+++ b/MainPage.xaml.h
@@ -24,6 +24,7 @@
 

 namespace RingClientUWP

 {

+

 namespace Views {

 }

 public ref class MainPage sealed

@@ -51,5 +52,10 @@
 

     void _toggleSmartBoxButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);

     void showFrame(Windows::UI::Xaml::Controls::Frame^ frame);

+    void OnsummonMessageTextPage();

+    void OnsummonWelcomePage();

+    void OnsummonVideoPage();

+    void OnpressHangUpCall();

+    void OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code);

 };

 }
\ No newline at end of file
diff --git a/MessageTextPage.xaml.cpp b/MessageTextPage.xaml.cpp
index aca763d..aa539a1 100644
--- a/MessageTextPage.xaml.cpp
+++ b/MessageTextPage.xaml.cpp
@@ -16,8 +16,8 @@
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *

 **************************************************************************/

 #include "pch.h"

-

 #include "ContactsViewModel.h"

+

 #include "MainPage.xaml.h"

 

 #include "MessageTextPage.xaml.h"

@@ -44,25 +44,19 @@
 {

     InitializeComponent();

 

-    /* connect delegates. */

-    // REFACTO : useless ?

+    /* connect to delegates */

     RingD::instance->incomingAccountMessage += ref new IncomingAccountMessage([&](String^ accountId,

-    String^ from, String^ payload) {

-    });

-    ContactsViewModel::instance->notifyNewConversationMessage += ref new NotifyNewConversationMessage([&](

-    bool isContactNotSelected) {

-        if (!isContactNotSelected) {

-            /* if the contact is selected that means we should scroll down */

-            scrollDown();

-        }

-

+    String^ fromRingId, String^ payload) {

+        scrollDown();

     });

 }

 

 void

 RingClientUWP::Views::MessageTextPage::updatePageContent()

 {

-    auto contact = ContactsViewModel::instance->selectedContact;

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+    auto contact = item->_contact;

+

     if (!contact)

         return;

 

@@ -96,7 +90,9 @@
 void

 RingClientUWP::Views::MessageTextPage::sendMessage()

 {

-    auto contact = ContactsViewModel::instance->selectedContact;

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+    auto contact = item->_contact;

+

     auto txt = _messageTextBox_->Text;

 

     /* empty the textbox */

diff --git a/RingD.cpp b/RingD.cpp
index 3187639..2508fb8 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -67,7 +67,8 @@
     std::string accountId3(accountId2.begin(), accountId2.end());

 

     /* recipient */

-    auto contact = ContactsViewModel::instance->selectedContact;

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+    auto contact = item->_contact;

     auto toRingId = contact->ringID_;

     std::wstring toRingId2(toRingId->Begin());

     std::string toRingId3(toRingId2.begin(), toRingId2.end());

@@ -197,7 +198,7 @@
                     CoreDispatcherPriority::Normal, ref new DispatchedHandler([=]()

                 {

                     incomingCall(accountId2, callId2, from2);

-                    stateChange(callId2, "incoming call", 0);

+                    stateChange(callId2, CallStatus::INCOMING_RINGING, 0);

                 }));

             }),

             DRing::exportable_callback<DRing::CallSignal::StateChange>([this](

@@ -213,11 +214,13 @@
                 auto callId2 = toPlatformString(callId);

                 auto state2 = toPlatformString(state);

 

+                auto state3 = getCallStatus(state2);

+

 

                 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(

                     CoreDispatcherPriority::Low, ref new DispatchedHandler([=]()

                 {

-                    stateChange(callId2, state2, code);

+                    stateChange(callId2, state3, code);

                 }));

             }),

             DRing::exportable_callback<DRing::ConfigurationSignal::IncomingAccountMessage>([&](

@@ -414,3 +417,23 @@
         tasksList_.pop();

     }

 }

+

+CallStatus RingClientUWP::RingD::getCallStatus(String^ state)

+{

+    if (state == "INCOMING")

+        return CallStatus::INCOMING_RINGING;

+

+    if (state == "CURRENT")

+        return CallStatus::IN_PROGRESS;

+

+    if (state == "OVER")

+        return CallStatus::ENDED;

+

+    if (state == "RINGING")

+        return CallStatus::OUTGOING_RINGING;

+

+    if (state == "CONNECTING")

+        return CallStatus::SEARCHING;

+

+    return CallStatus::NONE;

+}

diff --git a/RingD.h b/RingD.h
index 0bcfbdb..06334a6 100644
--- a/RingD.h
+++ b/RingD.h
@@ -24,7 +24,7 @@
 

 /* delegate */

 delegate void IncomingCall(String^ accountId, String^ callId, String^ from);

-delegate void StateChange(String^ callId, String^ state, int code);

+delegate void StateChange(String^ callId, CallStatus state, int code);

 delegate void IncomingAccountMessage(String^ accountId, String^ from, String^ payload);

 delegate void Calling(Call^ call);

 

@@ -104,6 +104,7 @@
     /* functions */

     RingD(); // singleton

     void dequeueTasks();

+    CallStatus getCallStatus(String^ state);

 

     /* members */

     std::string localFolder_;

diff --git a/SmartPanel.xaml b/SmartPanel.xaml
index 4431fcc..3876183 100644
--- a/SmartPanel.xaml
+++ b/SmartPanel.xaml
@@ -21,11 +21,18 @@
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       xmlns:local="using:RingClientUWP"

       xmlns:controls="using:RingClientUWP.Controls"

+      xmlns:views="using:RingClientUWP.Views"

       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

       mc:Ignorable="d">

 

     <Page.Resources>

+        <!-- converters -->

+        <views:NewMessageBubleNotification x:Key="_NewMessageBubleNotification_" />

+        <views:IncomingVisibility x:Key="_IncomingVisibility_" />

+        <views:OutGoingVisibility x:Key="_OutGoingVisibility_" />

+        <views:HasAnActiveCall x:Key="_HasAnActiveCall_" />

+

         <Style x:Key="addContactTextBoxStyle"

            TargetType="TextBox">

             <Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}"/>

@@ -146,15 +153,6 @@
                             <TranslateTransform X="17" Y="-14"/>

                         </Border.RenderTransform>

                     </Border>

-                    <Border x:Name="_visualNotificationNewMessage_"

-                            Visibility="{x:Bind notificationNewMessage, Mode=OneWay}"

-                            Style="{StaticResource BorderStyle2}">

-                        <TextBlock Text="{x:Bind unreadMessages, Mode=OneWay}"

-                                   Style="{StaticResource TextStyle3}"/>

-                        <Border.RenderTransform>

-                            <TranslateTransform X="-17" Y="-14"/>

-                        </Border.RenderTransform>

-                    </Border>

                     <Grid Grid.Column="1">

                         <Grid.RowDefinitions>

                             <RowDefinition Height="30"/>

@@ -166,42 +164,8 @@
                                     Text="{x:Bind name_}"

                                     TextTrimming="CharacterEllipsis">

                         </TextBlock>

-                        <!-- call status. REFACTO : REMOVE CODE BELOW -->

-                        <!--<StackPanel MaxWidth="240"

-                                    MinWidth="240"

-                                    Grid.Row="1"

-                                    HorizontalAlignment="Left">

-                            <TextBlock x:Name="_contactCallStatus_"

-                                       Foreground="DarkGray"

-                                       Text="{x:Bind _call.state, Mode=OneWay}"

-                                       Visibility="Visible"

-                                       HorizontalAlignment="Center">

-                            </TextBlock>

-                        </StackPanel>-->

                     </Grid>

                 </Grid>

-                <!-- REFACTO : REMOVE CODE BELOW -->

-                <!-- button bar for accept/reject or cancel call. -->

-                <!-- nb : dont use Visibility with the grid, use the height of the hosting row (_contactBar_). -->

-                <!--<Grid Width="320"

-                      HorizontalAlignment="Left"

-                      Grid.Row="2"

-                      Background="DarkGray">

-                    <StackPanel Orientation="Horizontal"

-                                Grid.Row="0"

-                                HorizontalAlignment="Center">

-                        <Button x:Name="_acceptIncomingCallBtn_"

-                                Click="_acceptIncomingCallBtn__Click"

-                            VerticalAlignment="Center"

-                            HorizontalAlignment="Center"

-                            Content="Accept"/>

-                        <Button x:Name="_rejectIncomingCallBtn_"

-                                Click="_rejectIncomingCallBtn__Click"

-                            VerticalAlignment="Center"

-                            HorizontalAlignment="Center"

-                            Content="Reject"/>

-                    </StackPanel>

-                </Grid>-->

             </Grid>

         </DataTemplate>

         <!-- template for accounts. -->

@@ -303,40 +267,127 @@
                       x:DataType="controls:SmartPanelItem">

             <Grid PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited">

                 <Grid.RowDefinitions>

+                    <!-- row definition for the contact. -->

                     <RowDefinition Height="auto"/>

+                    <!-- row definition for the incoming call bar. -->

+                    <RowDefinition Height="auto"/>

+                    <!-- row definition for the outgoing call bar. -->

                     <RowDefinition Height="auto"/>

                 </Grid.RowDefinitions>

-                <ListBoxItem x:Name="_contactItem_"

-                             Padding="0"

-                             Margin="0"

-                             Grid.Row="0"

-                             PointerReleased="_contactItem__PointerReleased"

-                             ContentTemplate="{StaticResource ContactTemplate}"

-                             Content="{x:Bind _contact, Mode=OneWay}"/>

-                <ListBoxItem Grid.Row="1"

-                             Visibility="{x:Bind _IncomingCallBar, Mode=OneWay}"

-                             Padding="0"

-                             Margin="0"

-                             ContentTemplate="{StaticResource IncomingCallTemplate}"

-                             Content="{x:Bind _call, Mode=OneWay}"/>

-                <Button Grid.Row="0"

-                        HorizontalAlignment="Left"

-                        Visibility="{x:Bind _callBar, Mode=OneWay}"

-                        Content="call"

-                        Padding="0"

-                        Click="_callContact__Click"

-                        VerticalAlignment="Bottom"

-                        Margin="10">

-                    <Button.RenderTransform>

-                        <TranslateTransform X="160"/>

-                    </Button.RenderTransform>

-                </Button>

-                <ListBoxItem Grid.Row="1"

-                             Visibility="{x:Bind _OutGoingCallBar, Mode=OneWay}"

-                             Padding="0"

-                             Margin="0"

-                             ContentTemplate="{StaticResource OutGoingCallTemplate}"

-                             Content="{x:Bind _call, Mode=OneWay}"/>

+                <!--helper to detect mouse overing-->

+                <Rectangle Fill="Transparent" Grid.Row="0"/>

+                <!-- contact. -->

+                <Grid Grid.Row="0">

+                    <Grid.ColumnDefinitions>

+                        <ColumnDefinition Width="310"/>

+                    </Grid.ColumnDefinitions>

+                    <Grid.RowDefinitions>

+                        <RowDefinition Height="60"/>

+                        <!-- use the height of _contactBar_ to make it visible or collapsed. -->

+                        <RowDefinition x:Name="_contactBar_"

+                                       Height="{x:Bind _contact._contactBarHeight, Mode=OneWay}"/>

+                    </Grid.RowDefinitions>

+                    <Grid Grid.Row="0">

+                        <Grid.ColumnDefinitions>

+                            <ColumnDefinition Width="60"/>

+                            <ColumnDefinition Width="*"

+                                              MinWidth="200"/>

+                        </Grid.ColumnDefinitions>

+                        <Image x:Name="_contactAvatar_"

+                               VerticalAlignment="Center"

+                               HorizontalAlignment="Center"

+                               Grid.Column="0"

+                               Width="55"

+                               Height="55"

+                               Source="Assets\TESTS\contactAvatar.png"/>

+                        <!-- visual notifications. -->

+                        <Border x:Name="_visualNotificationVideoChat_"

+                            Visibility="Collapsed"

+                            Style="{StaticResource BorderStyle1}">

+                            <TextBlock Text="&#xE8AA;"

+                                   Style="{StaticResource TextSegoeStyle1}"/>

+                            <Border.RenderTransform>

+                                <TranslateTransform X="17" Y="-14"/>

+                            </Border.RenderTransform>

+                        </Border>

+                        <Border x:Name="_visualNotificationNewMessage_"

+                            Visibility="{x:Bind _contact._unreadMessages, Converter={StaticResource _NewMessageBubleNotification_}, Mode=OneWay}"

+                            Style="{StaticResource BorderStyle2}">

+                            <TextBlock Text="{x:Bind _contact._unreadMessages, Mode=OneWay}"

+                                   Style="{StaticResource TextStyle3}"/>

+                            <Border.RenderTransform>

+                                <TranslateTransform X="-17" Y="-14"/>

+                            </Border.RenderTransform>

+                        </Border>

+

+                        <Grid Grid.Column="1">

+                            <Grid.RowDefinitions>

+                                <RowDefinition Height="30"/>

+                                <RowDefinition Height="30"/>

+                            </Grid.RowDefinitions>

+                            <!-- name of the contact. -->

+                            <TextBlock  x:Name="_contactName_"

+                                    Grid.Row="0"

+                                    Text="{x:Bind _contact.name_}"

+                                    TextTrimming="CharacterEllipsis">

+                            </TextBlock>

+                            <!-- call button. -->

+                            <Button Grid.Row="0"

+                                    Visibility="{x:Bind _hovered, Mode=OneWay}"

+                                    Click="_callContact__Click"

+                                    VerticalAlignment="Bottom"

+                                    HorizontalAlignment="Left"

+                                    Margin="10,0"

+                                    Style="{StaticResource roundButtonTemplate}"

+                                    FontFamily="Segoe MDL2 Assets"

+                                    Content="&#xE116;">

+                                <Button.RenderTransform>

+                                    <TranslateTransform X="90" Y="25"/>

+                                </Button.RenderTransform>

+                            </Button>

+                        </Grid>

+                    </Grid>

+                </Grid>

+                <!-- incomming call bar. -->

+                <Grid Width="320"

+                      Grid.Row="1"

+                      HorizontalAlignment="Left"

+                      Background="DarkGray">

+                    <Grid.RowDefinitions>

+                        <RowDefinition Height="auto"/>

+                        <RowDefinition Height="auto"/>

+                    </Grid.RowDefinitions>

+                    <TextBlock x:Name="_incommingCallStatus_"

+                           Grid.Row="0"

+                           Foreground="White"

+                           Text="{x:Bind _call.state, Mode=OneWay}"

+                           Visibility="{x:Bind _call.state, Converter={StaticResource _HasAnActiveCall_}, Mode=OneWay}"

+                           HorizontalAlignment="Center">

+                    </TextBlock>

+                    <StackPanel Orientation="Horizontal"

+                                Visibility="Visible"

+                                Grid.Row="1"

+                                HorizontalAlignment="Center">

+                        <Button x:Name="_acceptIncomingCallBtn_"

+                            Click="_acceptIncomingCallBtn__Click"

+                            Visibility="{x:Bind _call.state, Converter={StaticResource _IncomingVisibility_}, Mode=OneWay}"

+                            VerticalAlignment="Center"

+                            HorizontalAlignment="Center"

+                            Content="Accept"/>

+                        <Button x:Name="_rejectIncomingCallBtn_"

+                            Click="_rejectIncomingCallBtn__Click"

+                            Visibility="{x:Bind _call.state, Converter={StaticResource _IncomingVisibility_}, Mode=OneWay}"

+                            VerticalAlignment="Center"

+                            HorizontalAlignment="Center"

+                            Content="Reject"/>

+                        <Button x:Name="_cancelCallBtn_"

+                            Click="_cancelCallBtn__Click"

+                            Visibility="{x:Bind _call.state, Converter={StaticResource _OutGoingVisibility_}, Mode=OneWay}"

+                            VerticalAlignment="Center"

+                            HorizontalAlignment="Center"

+                            Content="Cancel"/>

+                    </StackPanel>

+                </Grid>

             </Grid>

         </DataTemplate>

     </Page.Resources>

@@ -409,7 +460,7 @@
             </Grid>

 

             <!--sub menus like the accounts list or the share menu are just below, technicaly they are nested inside the

-            same row. To sumon them we use the visibility of their own grid, by linking it to a toggle button-->

+            same row. To summon them we use the visibility of their own grid, by linking it to a toggle button-->

 

             <!-- accounts menu. -->

             <Grid x:Name="_accountsMenuGrid_"

diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp
index a61c161..8aec15d 100644
--- a/SmartPanel.xaml.cpp
+++ b/SmartPanel.xaml.cpp
@@ -77,8 +77,9 @@
 

         auto item = SmartPanelItemsViewModel::instance->findItem(contact);

         item->_call = call;

+

     });

-    RingD::instance->stateChange += ref new StateChange([this](String^ callId, String^ state, int code) {

+    RingD::instance->stateChange += ref new StateChange([this](String^ callId, CallStatus state, int code) {

         auto call = CallsViewModel::instance->findCall(callId);

 

         if (call == nullptr)

@@ -91,18 +92,11 @@
             return;

         }

 

-        if (call->state == "incoming call")

-            item->_IncomingCallBar = Windows::UI::Xaml::Visibility::Visible;

+        call->state = state;

 

-        if (call->state == "CURRENT") {

-            item->_IncomingCallBar = Windows::UI::Xaml::Visibility::Collapsed;

-            item->_OutGoingCallBar = Windows::UI::Xaml::Visibility::Collapsed;

-        }

+        if (state == CallStatus::IN_PROGRESS)

+            _smartList_->SelectedIndex = SmartPanelItemsViewModel::instance->getIndex(call);

 

-        if (call->state == "") {

-            item->_IncomingCallBar = Windows::UI::Xaml::Visibility::Collapsed;

-            item->_OutGoingCallBar = Windows::UI::Xaml::Visibility::Collapsed;

-        }

     });

 

 

@@ -129,10 +123,8 @@
             return;

         }

 

-        /* use underscore to differentiate states from UI, we need to think more about states management */

-        call->state = "_calling_";

+        call->state = CallStatus::SEARCHING;

 

-        item->_OutGoingCallBar = Windows::UI::Xaml::Visibility::Visible;

         item->_call = call;

     });

 

@@ -253,12 +245,31 @@
 void

 SmartPanel::_smartList__SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)

 {

-    auto listbox = safe_cast<ListBox^>(sender);

-    auto item = safe_cast<SmartPanelItem^>(listbox->SelectedItem);

+    auto listbox = dynamic_cast<ListBox^>(sender);

+    auto item = dynamic_cast<SmartPanelItem^>(listbox->SelectedItem);

+    SmartPanelItemsViewModel::instance->_selectedItem = item;

 

-    Contact^ contact = (item) ? safe_cast<Contact^>(item->_contact) : nullptr;

+    if (!item) {

+        summonWelcomePage();

+        return;

+    }

 

-    ContactsViewModel::instance->selectedContact = contact;

+    auto call = item->_call;

+    if (call) {

+        auto state = call->state;

+        if (state == CallStatus::IN_PROGRESS) {

+            summonVideoPage();

+            return;

+        }

+    }

+

+    auto contact = item->_contact;

+    if (contact) {

+        summonMessageTextPage();

+        contact->_unreadMessages = 0;

+        ContactsViewModel::instance->saveContactsToFile();

+        return;

+    }

 }

 

 void

@@ -303,7 +314,8 @@
 void RingClientUWP::Views::SmartPanel::_rejectIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)

 {

     auto button = dynamic_cast<Button^>(e->OriginalSource);

-    auto call = dynamic_cast<Call^>(button->DataContext);

+    auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);

+    auto call = item->_call;

 

     call->refuse();

 }

@@ -312,9 +324,8 @@
 void RingClientUWP::Views::SmartPanel::_acceptIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)

 {

     auto button = dynamic_cast<Button^>(e->OriginalSource);

-    auto call = dynamic_cast<Call^>(button->DataContext);

-

-    _smartList_->SelectedIndex = SmartPanelItemsViewModel::instance->getIndex(call);

+    auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);

+    auto call = item->_call;

 

     call->accept();

 }

@@ -326,8 +337,6 @@
     auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);

     auto contact = item->_contact;

 

-    _smartList_->SelectedIndex = SmartPanelItemsViewModel::instance->getIndex(contact);

-

     RingD::instance->placeCall(contact);

 }

 

@@ -335,7 +344,8 @@
 void RingClientUWP::Views::SmartPanel::_cancelCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)

 {

     auto button = dynamic_cast<Button^>(e->OriginalSource);

-    auto call = dynamic_cast<Call^>(button->DataContext);

+    auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);

+    auto call = item->_call;

 

     call->cancel();

 }

@@ -347,7 +357,7 @@
     auto listBoxItem = dynamic_cast<ListBoxItem^>(sender);

     auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext);

 

-    item->_callBar = Windows::UI::Xaml::Visibility::Visible;

+    item->_hovered = Windows::UI::Xaml::Visibility::Visible;

 }

 

 

@@ -357,7 +367,7 @@
     auto grid = dynamic_cast<Grid^>(sender);

     auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext);

 

-    item->_callBar = Windows::UI::Xaml::Visibility::Collapsed;

+    item->_hovered = Windows::UI::Xaml::Visibility::Collapsed;

 }

 

 

@@ -371,4 +381,77 @@
     else

         _smartList_->SelectedItem = nullptr;

 

-}
\ No newline at end of file
+}

+

+Object ^ RingClientUWP::Views::IncomingVisibility::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    auto state = static_cast<CallStatus>(value);

+    if (state == CallStatus::INCOMING_RINGING)

+        return  Windows::UI::Xaml::Visibility::Visible;

+    else

+        return  Windows::UI::Xaml::Visibility::Collapsed;

+}

+

+Object ^ RingClientUWP::Views::IncomingVisibility::ConvertBack(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    throw ref new Platform::NotImplementedException();

+}

+

+RingClientUWP::Views::IncomingVisibility::IncomingVisibility()

+{}

+

+

+Object ^ RingClientUWP::Views::OutGoingVisibility::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    auto state = static_cast<CallStatus>(value);

+

+    if (state == CallStatus::SEARCHING || state == CallStatus::OUTGOING_RINGING)

+        return  Windows::UI::Xaml::Visibility::Visible;

+    else

+        return  Windows::UI::Xaml::Visibility::Collapsed;

+}

+

+Object ^ RingClientUWP::Views::OutGoingVisibility::ConvertBack(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    throw ref new Platform::NotImplementedException();

+}

+

+RingClientUWP::Views::OutGoingVisibility::OutGoingVisibility()

+{}

+

+Object ^ RingClientUWP::Views::HasAnActiveCall::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    auto state = static_cast<CallStatus>(value);

+

+    if (state == CallStatus::NONE || state == CallStatus::ENDED)

+        return Windows::UI::Xaml::Visibility::Collapsed;

+    else

+        return Windows::UI::Xaml::Visibility::Visible;

+}

+

+Object ^ RingClientUWP::Views::HasAnActiveCall::ConvertBack(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    throw ref new Platform::NotImplementedException();

+

+}

+

+RingClientUWP::Views::HasAnActiveCall::HasAnActiveCall()

+{}

+

+Object ^ RingClientUWP::Views::NewMessageBubleNotification::Convert(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    auto unreadMessages = static_cast<uint32>(value);

+

+    if (unreadMessages > 0)

+        return Windows::UI::Xaml::Visibility::Visible;

+

+    return Windows::UI::Xaml::Visibility::Collapsed;

+}

+

+Object ^ RingClientUWP::Views::NewMessageBubleNotification::ConvertBack(Object ^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object ^ parameter, String ^ language)

+{

+    throw ref new Platform::NotImplementedException();

+}

+

+RingClientUWP::Views::NewMessageBubleNotification::NewMessageBubleNotification()

+{}

diff --git a/SmartPanel.xaml.h b/SmartPanel.xaml.h
index 58c9f05..c017617 100644
--- a/SmartPanel.xaml.h
+++ b/SmartPanel.xaml.h
@@ -22,11 +22,41 @@
 {

 

 delegate void ToggleSmartPan();

-delegate void SumonMessageTextPage();

-delegate void SumonVideoPage();

+delegate void SummonMessageTextPage();

+delegate void SummonVideoPage();

+delegate void SummonWelcomePage();

 

 namespace Views

 {

+

+public ref class IncomingVisibility sealed : IValueConverter {

+public:

+    virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, String^ language);

+    virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName  targetType, Object^ parameter, String^ language);

+    IncomingVisibility();

+};

+

+public ref class OutGoingVisibility sealed : IValueConverter {

+public:

+    virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, String^ language);

+    virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName  targetType, Object^ parameter, String^ language);

+    OutGoingVisibility();

+};

+

+public ref class HasAnActiveCall sealed : IValueConverter {

+public:

+    virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, String^ language);

+    virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName  targetType, Object^ parameter, String^ language);

+    HasAnActiveCall();

+};

+

+public ref class NewMessageBubleNotification sealed : IValueConverter {

+public:

+    virtual Object^ Convert(Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Object^ parameter, String^ language);

+    virtual Object^ ConvertBack(Object^ value, Windows::UI::Xaml::Interop::TypeName  targetType, Object^ parameter, String^ language);

+    NewMessageBubleNotification();

+};

+

 public ref class SmartPanel sealed

 {

 public:

@@ -36,8 +66,9 @@
 internal:

     enum class Mode { Minimized, Normal };

     event ToggleSmartPan^ toggleSmartPan;

-    event SumonMessageTextPage^ sumonMessageTextPage;

-    event SumonVideoPage^ sumonVideoPage;

+    event SummonMessageTextPage^ summonMessageTextPage;

+    event SummonVideoPage^ summonVideoPage;

+    event SummonWelcomePage^ summonWelcomePage;

     void setMode(RingClientUWP::Views::SmartPanel::Mode mode);

 

 private:

diff --git a/SmartPanelItem.cpp b/SmartPanelItem.cpp
index ab986a6..d93b454 100644
--- a/SmartPanelItem.cpp
+++ b/SmartPanelItem.cpp
@@ -30,7 +30,10 @@
 using namespace ViewModel;

 

 SmartPanelItem::SmartPanelItem()

-{}

+{

+    /* create an empty call to avoid the call bar */

+    _call = ref new Call("", "", "");

+}

 

 void

 SmartPanelItem::NotifyPropertyChanged(String^ propertyName)

diff --git a/SmartPanelItem.h b/SmartPanelItem.h
index aa5484b..0803fb1 100644
--- a/SmartPanelItem.h
+++ b/SmartPanelItem.h
@@ -32,42 +32,6 @@
 

     virtual event PropertyChangedEventHandler^ PropertyChanged;

     property Contact^ _contact;

-    property Visibility _IncomingCallBar

-    {

-        Visibility get()

-        {

-            return incomingCallBar_;

-        }

-        void set(Visibility value)

-        {

-            incomingCallBar_ = value;

-            PropertyChanged(this, ref new PropertyChangedEventArgs("_IncomingCallBar"));

-        }

-    }

-    property Visibility _OutGoingCallBar

-    {

-        Visibility get()

-        {

-            return outGoingCallBar_;

-        }

-        void set(Visibility value)

-        {

-            outGoingCallBar_ = value;

-            PropertyChanged(this, ref new PropertyChangedEventArgs("_OutGoingCallBar"));

-        }

-    }

-    property Visibility _callBar

-    {

-        Visibility get()

-        {

-            return callBar_;

-        }

-        void set(Visibility value)

-        {

-            callBar_ = value;

-            PropertyChanged(this, ref new PropertyChangedEventArgs("_callBar"));

-        }

-    }

     property Call^ _call

     {

         Call^ get()

@@ -80,15 +44,26 @@
             PropertyChanged(this, ref new PropertyChangedEventArgs("_call"));

         }

     }

+    property Visibility _hovered

+    {

+        Visibility get()

+        {

+            return hovered_;

+        }

+        void set(Visibility value)

+        {

+            hovered_ = value;

+            PropertyChanged(this, ref new PropertyChangedEventArgs("_hovered"));

+        }

+    }

 

 protected:

     void NotifyPropertyChanged(String^ propertyName);

 

 private:

-    Visibility incomingCallBar_ = Visibility::Collapsed;

-    Visibility outGoingCallBar_ = Visibility::Collapsed;

-    Visibility callBar_ = Visibility::Collapsed;

     Call^ call_;

+    Visibility hovered_ = Visibility::Collapsed;

+

 };

 }

 }

diff --git a/SmartPanelItemsViewModel.h b/SmartPanelItemsViewModel.h
index 52e1c86..7bcdfe7 100644
--- a/SmartPanelItemsViewModel.h
+++ b/SmartPanelItemsViewModel.h
@@ -26,7 +26,6 @@
 

 namespace RingClientUWP

 {

-

 namespace ViewModel {

 public ref class SmartPanelItemsViewModel sealed

 {

@@ -55,7 +54,18 @@
         }

     }

 

-    /* events */

+    property SmartPanelItem^ _selectedItem

+    {

+        SmartPanelItem^ get()

+        {

+            return currentItem_;

+        }

+        void set(SmartPanelItem^ value)

+        {

+            oldItem_ = currentItem_;

+            currentItem_ = value;

+        }

+    }

 

 private:

     SmartPanelItemsViewModel(); // singleton

diff --git a/Styles.xaml b/Styles.xaml
index d010259..3f5854a 100644
--- a/Styles.xaml
+++ b/Styles.xaml
@@ -290,5 +290,20 @@
             </Setter.Value>

         </Setter>

     </Style>

+    <!-- rounded button for call -->

+    <Style x:Key ="roundButtonTemplate" TargetType ="Button">

+        <Setter Property ="Foreground" Value ="Black"/>

+        <Setter Property ="FontWeight" Value ="Bold"/>

+        <Setter Property ="Template">

+            <Setter.Value>

+                <ControlTemplate TargetType ="Button">

+                    <Grid>

+                        <Ellipse Name ="OuterRing" Width ="30" Height ="30" Fill ="LightBlue"/>

+                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>

+                    </Grid>

+                </ControlTemplate>

+            </Setter.Value>

+        </Setter>

+    </Style>

 

 </ResourceDictionary>

diff --git a/VideoPage.xaml.cpp b/VideoPage.xaml.cpp
index 70eed4a..112741c 100644
--- a/VideoPage.xaml.cpp
+++ b/VideoPage.xaml.cpp
@@ -21,6 +21,7 @@
 #include "VideoPage.xaml.h"

 

 using namespace RingClientUWP::Views;

+using namespace ViewModel;

 

 using namespace Concurrency;

 using namespace Platform;

@@ -56,10 +57,9 @@
 

 void RingClientUWP::Views::VideoPage::updatePageContent()

 {

-    auto selectedContact = ViewModel::ContactsViewModel::instance->selectedContact;

-    Contact^ contact = selectedContact?

-        ViewModel::SmartPanelItemsViewModel::instance->findItem(selectedContact)->_contact:

-        nullptr;

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+    auto contact = (item) ? item->_contact : nullptr;

+

     if (!contact)

         return;

 

@@ -93,7 +93,9 @@
 void

 RingClientUWP::Views::VideoPage::sendMessage()

 {

-    auto contact = ViewModel::ContactsViewModel::instance->selectedContact;

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+    auto contact = item->_contact;

+

     auto txt = _messageTextBox_->Text;

 

     /* empty the textbox */

@@ -118,10 +120,9 @@
 

 void RingClientUWP::Views::VideoPage::_btnHangUp__Tapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e)

 {

-    Contact^ selectedContact = ViewModel::ContactsViewModel::instance->selectedContact;

-    Call^ call = selectedContact?

-        ViewModel::SmartPanelItemsViewModel::instance->findItem(selectedContact)->_call:

-        nullptr;

+    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

+    auto call = item->_call;

+

     if (call)

         RingD::instance->hangUpCall(call);

     pressHangUpCall();