diff --git a/Call.cpp b/Call.cpp index 534bc3176146d51e3fc556dae32df319ce9f97fb..24e4353c1e7bd65686b86c8dc0171c01e5c0beb5 100644 --- a/Call.cpp +++ b/Call.cpp @@ -25,19 +25,20 @@ using namespace Windows::UI::Core; using namespace RingClientUWP; -Call::Call(String^ accountId, String^ callId, String^ from) +Call::Call(String^ accountIdz, String^ callIdz, String^ fromz) { - this->accountId = accountId; - this->callId = callId; - this->from = from; + this->accountId = accountIdz; + this->callId = callIdz; + this->from = fromz; - this->state = ""; + this->state = "incoming call"; this->code = -1; } void RingClientUWP::Call::stateChange(String ^ state, int code) { this->state = state; + PropertyChanged(this, ref new PropertyChangedEventArgs("state")); this->code = code; } diff --git a/CallsViewModel.cpp b/CallsViewModel.cpp index acaa69ec15d068650fc16e50f3022d1718b02c83..cf6166f891a1be86c17814732151d629d126ee2d 100644 --- a/CallsViewModel.cpp +++ b/CallsViewModel.cpp @@ -29,21 +29,30 @@ CallsViewModel::CallsViewModel() CallsList_ = ref new Vector<Call^>(); /* connect to delegates. */ + RingD::instance->incomingCall += ref new RingClientUWP::IncomingCall([&]( String^ accountId, String^ callId, String^ from) { - addNewCall(accountId, callId, from); + auto call = addNewCall(accountId, callId, from); + 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); + callStatusUpdated(call); + return; + } call->stateChange(state, code); + callStatusUpdated(call); return; } } WNG_("Call not found"); }); - } Call^ @@ -51,5 +60,10 @@ RingClientUWP::ViewModel::CallsViewModel::addNewCall(String^ accountId, String^ { auto call = ref new Call(accountId, callId, from); CallsList_->Append(call); - return nullptr; + return call; } + +void RingClientUWP::ViewModel::CallsViewModel::clearCallsList() +{ + CallsList_->Clear(); +} \ No newline at end of file diff --git a/CallsViewModel.h b/CallsViewModel.h index f5852524cb94dcfc741b63f210c4816dc6a8600e..553455e423d2fafd78f1f22c073aba9c89bed56d 100644 --- a/CallsViewModel.h +++ b/CallsViewModel.h @@ -20,7 +20,9 @@ using namespace Platform::Collections; namespace RingClientUWP { - +/* delegate */ +delegate void CallRecieved(Call^ call); +delegate void CallStatusUpdated(Call^ call); namespace ViewModel { public ref class CallsViewModel sealed @@ -38,6 +40,8 @@ internal: /* functions */ Call^ addNewCall(String^ accountId, String^ callId, String^ from); + void clearCallsList(); + void setState(String^ callId, String^ state, int code); /* properties */ property Vector<Call^>^ CallsList @@ -49,6 +53,8 @@ internal: } /* events */ + event CallRecieved^ callRecieved; + event CallStatusUpdated^ callStatusUpdated; private: CallsViewModel(); // singleton diff --git a/Contact.cpp b/Contact.cpp index 6415b335b6c0b462a4ec6bb0aa7d2c2875739eb6..0f70c832d75cb9c819420b9edb13fbac33278434 100644 --- a/Contact.cpp +++ b/Contact.cpp @@ -42,8 +42,6 @@ Contact::Contact(String^ name, if (GUID_ == nullptr) GUID_ = Utils::GetNewGUID(); - //RingDebug::instance->print(Utils::toString(GUID_).c_str()); - // load conversation from disk conversation_ = ref new Conversation(); StorageFolder^ localfolder = ApplicationData::Current->LocalFolder; @@ -71,7 +69,7 @@ Contact::Contact(String^ name, }); notificationNewMessage_ = Windows::UI::Xaml::Visibility::Collapsed; - unreadMessages_ = unreadmessages; // not saved on disk yet (TO DO) + unreadMessages_ = unreadmessages; if(unreadMessages_) { notificationNewMessage = Windows::UI::Xaml::Visibility::Visible; diff --git a/Contact.h b/Contact.h index 71547784151981ac9adff78ddc897109b7c5e020..517d35c1c6827cb41012bdaa1792877a529166d3 100644 --- a/Contact.h +++ b/Contact.h @@ -71,6 +71,18 @@ public: return unreadMessages_.ToString(); } } + property Call^ _call + { + Call^ get() + { + return call_; + } + void set(Call^ call) + { + call_ = call; + PropertyChanged(this, ref new PropertyChangedEventArgs("_call")); + } + } internal: void saveConversationToFile(); @@ -85,7 +97,8 @@ private: Conversation^ conversation_; Visibility notificationNewMessage_; unsigned int unreadMessages_; - + Windows::UI::Xaml::GridLength contactBarHeight_; + Call^ call_; }; } diff --git a/ContactsViewModel.cpp b/ContactsViewModel.cpp index fb1c8d90a1f597f75e3895e0d4cd203b621bb713..68141b59701de8b291d60416b9f3ba1984adf865 100644 --- a/ContactsViewModel.cpp +++ b/ContactsViewModel.cpp @@ -64,6 +64,22 @@ ContactsViewModel::ContactsViewModel() saveContactsToFile(); } }); + CallsViewModel::instance->callRecieved += ref new RingClientUWP::CallRecieved([&]( + Call^ call) { + auto from = call->from; + auto contact = findContactByName(from); + + if (contact == nullptr) + contact = addNewContact(from, from); // contact checked inside addNewContact. + + bool isNotSelected = (contact != ContactsViewModel::instance->selectedContact) ? true : false; + + if (contact == nullptr) { + ERR_("contact not handled!"); + return; + } + contact->_call = call; + }); } diff --git a/ContactsViewModel.h b/ContactsViewModel.h index b4de756ec1d63b85f171f9f2178e833b690ce7fd..13cf1fb74c8c4ec1a41ea0ca81d315ed24357a94 100644 --- a/ContactsViewModel.h +++ b/ContactsViewModel.h @@ -30,6 +30,7 @@ delegate void NewContactSelected(); delegate void NoContactSelected(); delegate void ScreenConversationMessage(String^ accountId, String^ from, String^ payload); delegate void NotifyNewConversationMessage(); +delegate void ShowContactBar(); namespace ViewModel { public ref class ContactsViewModel sealed @@ -84,6 +85,7 @@ internal: event NoContactSelected^ noContactSelected; event ScreenConversationMessage^ screenConversationMessage; event NotifyNewConversationMessage^ notifyNewConversationMessage; + event ShowContactBar^ showContactBar; private: ContactsViewModel(); // singleton diff --git a/RingD.cpp b/RingD.cpp index 00eccbb30738ef423fa289f908550a54bd959cee..c58193f905c976019d7efcf4ce9ddce2ea3852da 100644 --- a/RingD.cpp +++ b/RingD.cpp @@ -102,6 +102,10 @@ void RingClientUWP::RingD::sendAccountTextMessage(String^ message) void RingClientUWP::RingD::startDaemon() { + // TODO (during refactoring) : use namespace + /* clear the calls list and instantiate the singleton (required) */ + RingClientUWP::ViewModel::CallsViewModel::instance->clearCallsList(); + create_task([&]() { using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>; @@ -123,13 +127,17 @@ RingClientUWP::RingD::startDaemon() auto callId2 = toPlatformString(callId); auto from2 = toPlatformString(from); - incomingCall(accountId2, callId2, from2); - + CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync( + CoreDispatcherPriority::Normal, ref new DispatchedHandler([=]() + { + incomingCall(accountId2, callId2, from2); + stateChange(callId2, "incoming call", 0); + })); }), DRing::exportable_callback<DRing::CallSignal::StateChange>([this]( - const std::string& callId, - const std::string& state, - int code) + const std::string& callId, + const std::string& state, + int code) { MSG_("<StateChange>"); MSG_("callId = " + callId); @@ -139,13 +147,17 @@ RingClientUWP::RingD::startDaemon() auto callId2 = toPlatformString(callId); auto state2 = toPlatformString(state); - stateChange(callId2, state2, code); + CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync( + CoreDispatcherPriority::Low, ref new DispatchedHandler([=]() + { + stateChange(callId2, state2, code); + })); }), DRing::exportable_callback<DRing::ConfigurationSignal::IncomingAccountMessage>([&]( - const std::string& accountId, - const std::string& from, - const std::map<std::string, std::string>& payloads) + const std::string& accountId, + const std::string& from, + const std::map<std::string, std::string>& payloads) { MSG_("<IncomingAccountMessage>"); MSG_("accountId = " + accountId); @@ -189,9 +201,9 @@ RingClientUWP::RingD::startDaemon() }; registerCallHandlers(getAppPathHandler); - DRing::init(static_cast<DRing::InitFlag>(DRing::DRING_FLAG_CONSOLE_LOG | - DRing::DRING_FLAG_DEBUG | - DRing::DRING_FLAG_AUTOANSWER)); + DRing::init(static_cast<DRing::InitFlag>(/*DRing::DRING_FLAG_CONSOLE_LOG | + DRing::DRING_FLAG_DEBUG |*/ + !DRing::DRING_FLAG_AUTOANSWER)); if (!DRing::start()) { ERR_("\ndaemon didn't start.\n"); @@ -233,21 +245,21 @@ RingD::dequeueTasks() case Request::None: break; case Request::AddRingAccount: - { - std::map<std::string, std::string> ringAccountDetails; - ringAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_ALIAS, accountName)); - ringAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_TYPE,"RING")); - DRing::addAccount(ringAccountDetails); - } - break; + { + std::map<std::string, std::string> ringAccountDetails; + ringAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_ALIAS, accountName)); + ringAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_TYPE,"RING")); + DRing::addAccount(ringAccountDetails); + } + break; case Request::AddSIPAccount: - { - std::map<std::string, std::string> sipAccountDetails; - sipAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_ALIAS, accountName + " (SIP)")); - sipAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_TYPE,"SIP")); - DRing::addAccount(sipAccountDetails); - } - break; + { + std::map<std::string, std::string> sipAccountDetails; + sipAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_ALIAS, accountName + " (SIP)")); + sipAccountDetails.insert(std::make_pair(ring::Conf::CONFIG_ACCOUNT_TYPE,"SIP")); + DRing::addAccount(sipAccountDetails); + } + break; default: break; } diff --git a/SmartPanel.xaml b/SmartPanel.xaml index 68baddf71ed74ddd32869153bed8650df51411b6..9736001f673a6a010aab5aa2ae8f5cf67bd4ca5b 100644 --- a/SmartPanel.xaml +++ b/SmartPanel.xaml @@ -66,42 +66,48 @@ <TranslateTransform X="-17" Y="-14"/> </Border.RenderTransform> </Border> - <!-- name of the contact. --> - <TextBlock x:Name="_contactName_" - Grid.Column="1" + <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 name_}"> - <TextBlock.RenderTransform> - <TranslateTransform X="8" Y="3"/> - </TextBlock.RenderTransform> - </TextBlock> + </TextBlock> + <!-- call status. --> + <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> <!-- 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="1" + Grid.Row="2" Background="DarkGray"> <StackPanel Orientation="Horizontal" + Grid.Row="0" HorizontalAlignment="Center"> <Button x:Name="_acceptIncomingCallBtn_" VerticalAlignment="Center" HorizontalAlignment="Center" - Style="{StaticResource ButtonStyle2}" - Content=""/> + Content="Accept"/> <Button x:Name="_rejectIncomingCallBtn_" VerticalAlignment="Center" HorizontalAlignment="Center" - Style="{StaticResource ButtonStyle2}" - Content=""/> + Content="Reject"/> </StackPanel> - <TextBlock x:Name="_contactCallStatus_" - Foreground="DarkGray" - Text="Incoming call" - HorizontalAlignment="Center"> - <TextBlock.RenderTransform> - <TranslateTransform Y="-30"/> - </TextBlock.RenderTransform> - </TextBlock> </Grid> </Grid> </DataTemplate> diff --git a/SmartPanel.xaml.h b/SmartPanel.xaml.h index 29e6a562e4eb0467bc3127cea92f4a33321f9288..4cd126804825bd8deb7c512528f4688886c44390 100644 --- a/SmartPanel.xaml.h +++ b/SmartPanel.xaml.h @@ -25,6 +25,7 @@ delegate void ToggleSmartPan(); delegate void SumonMessageTextPage(); delegate void SumonVideoPage(); + namespace Views { public ref class SmartPanel sealed diff --git a/pch.h b/pch.h index c2af724174c616e2999b413c6d9214e4902ac60f..daba86128aaa4612e42b153b014bea985165ef23 100644 --- a/pch.h +++ b/pch.h @@ -27,6 +27,7 @@ #include "Account.h" #include "AccountsViewModel.h" #include "Call.h" +#include "CallsViewModel.h" #include "Contact.h" #include "ContactsViewModel.h" #include "Conversation.h" diff --git a/ring-client-uwp.vcxproj.filters b/ring-client-uwp.vcxproj.filters index a79ef0414fc25d4cc1c6abd6156bb69dcc96b408..f738d4a12c1577ef8ba0782bbe4df68cc9250d33 100644 --- a/ring-client-uwp.vcxproj.filters +++ b/ring-client-uwp.vcxproj.filters @@ -68,9 +68,6 @@ </ClCompile> <ClCompile Include="LoadingPage.xaml.cpp" /> <ClCompile Include="Wizard.xaml.cpp" /> - <ClCompile Include="Call.cpp"> - <Filter>Common</Filter> - </ClCompile> <ClCompile Include="Conversation.cpp"> <Filter>Model</Filter> </ClCompile> @@ -80,6 +77,9 @@ <ClCompile Include="UserPreferences.cpp"> <Filter>Common</Filter> </ClCompile> + <ClCompile Include="Call.cpp"> + <Filter>Model</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="pch.h" /> @@ -113,9 +113,6 @@ </ClInclude> <ClInclude Include="LoadingPage.xaml.h" /> <ClInclude Include="Wizard.xaml.h" /> - <ClInclude Include="Call.h"> - <Filter>Common</Filter> - </ClInclude> <ClInclude Include="CallsViewModel.h"> <Filter>ModelViews</Filter> </ClInclude> @@ -125,6 +122,9 @@ <ClInclude Include="UserPreferences.h"> <Filter>Common</Filter> </ClInclude> + <ClInclude Include="Call.h"> + <Filter>Model</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Image Include="Assets\LockScreenLogo.scale-200.png">