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=""
+ 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="">
+ <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();