Commit 5750df0d authored by Nicolas Jager's avatar Nicolas Jager

call : make a call

- adds a button in the contact list box item to call it.
- adds button and logic to cancel an outgoing call.

Change-Id: I74da49acedca9f7ac0c1b62c859823e02ee960cf
Tuleap: #1028
parent 652ff7c3
......@@ -25,12 +25,16 @@ using namespace Windows::UI::Core;
using namespace RingClientUWP;
// REFACTORING : for the whole Call class, change "from" to "peer"
Call::Call(String^ accountIdz, String^ callIdz, String^ fromz)
{
this->accountId = accountIdz;
this->callId = callIdz;
this->from = fromz;
isOutGoing = false; // by default, we consider the call incomming, REFACTO : add this to the constructor params...
this->state = "incoming call";
this->code = -1;
}
......@@ -64,3 +68,8 @@ void RingClientUWP::Call::accept()
{
RingD::instance->acceptIncommingCall(this);
}
void RingClientUWP::Call::cancel()
{
RingD::instance->cancelOutGoingCall(this);
}
......@@ -35,6 +35,7 @@ public:
property String^ callId;
property String^ from;
property String^ state;
property bool isOutGoing;
property int code;
/* events */
......@@ -46,6 +47,7 @@ protected:
internal:
void refuse();
void accept();
void cancel();
};
}
......
......@@ -33,6 +33,7 @@ CallsViewModel::CallsViewModel()
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);
});
......@@ -56,9 +57,12 @@ CallsViewModel::CallsViewModel()
}
Call^
RingClientUWP::ViewModel::CallsViewModel::addNewCall(String^ accountId, String^ callId, String^ from)
RingClientUWP::ViewModel::CallsViewModel::addNewCall(String^ accountId, String^ callId, String^ peer)
{
auto call = ref new Call(accountId, callId, from);
if (accountId == "" | callId == "" | peer == "") {
WNG_("call can't be created");
}
auto call = ref new Call(accountId, callId, peer);
CallsList_->Append(call);
return call;
}
......
......@@ -125,6 +125,41 @@ void RingClientUWP::RingD::acceptIncommingCall(Call^ call)
tasksList_.push(ref new RingD::Task(Request::AcceptIncommingCall, call));
}
void RingClientUWP::RingD::placeCall(Contact^ contact)
{
auto to = contact->ringID_;
auto accountId = AccountsViewModel::instance->selectedAccount->accountID_;
auto to2 = Utils::toString(to);
auto accountId2 = Utils::toString(accountId);
auto callId2 = DRing::placeCall(accountId2, to2);
if (callId2 == "") {
WNG_("call not created, the daemon didn't return a call Id");
return;
}
auto callId = Utils::toPlatformString(callId2);
auto call = CallsViewModel::instance->addNewCall(accountId, callId, to);
call->isOutGoing = true;
if (call == nullptr) {
WNG_("call not created, nullptr reason");
return;
}
calling(call);
}
void
RingClientUWP::RingD::cancelOutGoingCall(Call^ call)
{
tasksList_.push(ref new RingD::Task(Request::CancelOutGoingCall, call));
}
void
RingClientUWP::RingD::startDaemon()
{
......@@ -221,7 +256,13 @@ RingClientUWP::RingD::startDaemon()
ref new DispatchedHandler([=]() {
reloadAccountList();
}));
})
}),
/* to remove from daemon API, this callback is never used */
//DRing::exportable_callback<DRing::CallSignal::NewCallCreated>([&](
// const std::string& accountId,
// const std::string& callId,
// const std::string& to)
//{ /*...*/ })
};
registerCallHandlers(callHandlers);
......@@ -313,6 +354,13 @@ RingD::dequeueTasks()
DRing::accept(callId2);
}
break;
case Request::CancelOutGoingCall:
{
auto callId = task->_call->callId;
auto callId2 = Utils::toString(callId);
DRing::hangUp(callId2);
}
break;
default:
break;
}
......
......@@ -26,6 +26,7 @@ namespace RingClientUWP
delegate void IncomingCall(String^ accountId, String^ callId, String^ from);
delegate void StateChange(String^ callId, String^ state, int code);
delegate void IncomingAccountMessage(String^ accountId, String^ from, String^ payload);
delegate void Calling(Call^ call);
public ref class RingD sealed
......@@ -60,6 +61,8 @@ internal:
void createSIPAccount(String^ alias);
void refuseIncommingCall(Call^ call);
void acceptIncommingCall(Call^ call);
void placeCall(Contact^ contact);
void cancelOutGoingCall(Call^ call);
/* TODO : move members */
bool hasConfig;
......@@ -69,6 +72,7 @@ internal:
event IncomingCall^ incomingCall;
event StateChange^ stateChange;
event IncomingAccountMessage^ incomingAccountMessage;
event Calling^ calling;
private:
/* sub classes */
......@@ -77,7 +81,8 @@ private:
AddRingAccount,
AddSIPAccount,
RefuseIncommingCall,
AcceptIncommingCall
AcceptIncommingCall,
CancelOutGoingCall
};
ref class Task
{
......
......@@ -77,8 +77,8 @@
Grid.Row="0"
Text="{x:Bind name_}">
</TextBlock>
<!-- call status. -->
<StackPanel MaxWidth="240"
<!-- call status. REFACTO : REMOVE CODE BELOW -->
<!--<StackPanel MaxWidth="240"
MinWidth="240"
Grid.Row="1"
HorizontalAlignment="Left">
......@@ -88,12 +88,13 @@
Visibility="Visible"
HorizontalAlignment="Center">
</TextBlock>
</StackPanel>
</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"
<!--<Grid Width="320"
HorizontalAlignment="Left"
Grid.Row="2"
Background="DarkGray">
......@@ -111,7 +112,7 @@
HorizontalAlignment="Center"
Content="Reject"/>
</StackPanel>
</Grid>
</Grid>-->
</Grid>
</DataTemplate>
<!-- template for accounts. -->
......@@ -149,11 +150,10 @@
Text="{x:Bind ringID_}"/>
</Grid>
</DataTemplate>
<!-- template for calls. -->
<DataTemplate x:Key="CallTemplate" x:DataType="local:Call">
<!-- template for incoming calls. -->
<DataTemplate x:Key="IncomingCallTemplate" x:DataType="local:Call">
<Grid Width="320"
HorizontalAlignment="Left"
Background="DarkGray">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
......@@ -182,10 +182,37 @@
</StackPanel>
</Grid>
</DataTemplate>
<!-- template for outgoing calls. -->
<DataTemplate x:Key="OutGoingCallTemplate" x:DataType="local:Call">
<Grid Width="320"
HorizontalAlignment="Left"
Background="DarkGray">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock x:Name="_contactCallStatus_"
Grid.Row="0"
Foreground="White"
Text="{x:Bind state, Mode=OneWay}"
Visibility="Visible"
HorizontalAlignment="Center">
</TextBlock>
<StackPanel Orientation="Horizontal"
Grid.Row="1"
HorizontalAlignment="Center">
<Button x:Name="_cancelCallBtn_"
Click="_cancelCallBtn__Click"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="Cancel"/>
</StackPanel>
</Grid>
</DataTemplate>
<!-- template for smartpanelitems. -->
<DataTemplate x:Key="SmartPanelItemsTemplate"
x:DataType="controls:SmartPanelItem">
<Grid>
<Grid PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
......@@ -193,16 +220,33 @@
<ListBoxItem x:Name="_contactItem_"
Padding="0"
Margin="0"
IsHitTestVisible="False"
Grid.Row="0"
PointerReleased="_contactItem__PointerReleased"
ContentTemplate="{StaticResource ContactTemplate}"
Content="{x:Bind _contact, Mode=OneWay}"/>
<ListBoxItem x:Name="_callItem_"
Grid.Row="1"
Visibility="{x:Bind _callBar, 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 CallTemplate}"
ContentTemplate="{StaticResource OutGoingCallTemplate}"
Content="{x:Bind _call, Mode=OneWay}"/>
</Grid>
</DataTemplate>
......
......@@ -93,13 +93,17 @@ SmartPanel::SmartPanel()
}
if (call->state == "incoming call")
item->_callBar = Windows::UI::Xaml::Visibility::Visible;
item->_IncomingCallBar = Windows::UI::Xaml::Visibility::Visible;
if (call->state == "CURRENT")
item->_callBar = Windows::UI::Xaml::Visibility::Collapsed;
if (call->state == "CURRENT") {
item->_IncomingCallBar = Windows::UI::Xaml::Visibility::Collapsed;
item->_OutGoingCallBar = Windows::UI::Xaml::Visibility::Collapsed;
}
if (call->state == "")
item->_callBar = Windows::UI::Xaml::Visibility::Collapsed;
if (call->state == "") {
item->_IncomingCallBar = Windows::UI::Xaml::Visibility::Collapsed;
item->_OutGoingCallBar = Windows::UI::Xaml::Visibility::Collapsed;
}
});
......@@ -109,6 +113,30 @@ SmartPanel::SmartPanel()
smartPanelItemsList_->Append(smartPanelItem);
});
RingD::instance->calling += ref new RingClientUWP::Calling([&](
Call^ call) {
auto from = call->from;
auto contact = ContactsViewModel::instance->findContactByName(from);
if (contact == nullptr) {
WNG_("cannot call the peer, contact not found!");
return;
}
auto item = findItem(contact);
if (item == nullptr) {
WNG_("cannot call the peer, smart panel item not found!");
return;
}
/* use underscore to differentiate states from UI, we need to think more about states management */
call->state = "_calling_";
item->_OutGoingCallBar = Windows::UI::Xaml::Visibility::Visible;
item->_call = call;
});
}
void
......@@ -228,13 +256,10 @@ SmartPanel::_smartList__SelectionChanged(Platform::Object^ sender, Windows::UI::
{
auto listbox = safe_cast<ListBox^>(sender);
auto item = safe_cast<SmartPanelItem^>(listbox->SelectedItem);
if (item != nullptr) {
auto contact = safe_cast<Contact^>(item->_contact);
ContactsViewModel::instance->selectedContact = contact;
}
else {
ContactsViewModel::instance->selectedContact = nullptr;
}
Contact^ contact = (item) ? safe_cast<Contact^>(item->_contact) : nullptr;
ContactsViewModel::instance->selectedContact = contact;
}
void
......@@ -269,7 +294,7 @@ void RingClientUWP::Views::SmartPanel::_ringTxtBx__KeyDown(Platform::Object^ sen
}
}
// REFACTO : change the name IncomingCall if used with OutGoingCall too.
void RingClientUWP::Views::SmartPanel::_rejectIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
auto button = dynamic_cast<Button^>(e->OriginalSource);
......@@ -306,4 +331,56 @@ SmartPanel::findItem(Call^ call)
return item;
return nullptr;
}
void
SmartPanel::_callContact__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
auto button = dynamic_cast<Button^>(e->OriginalSource);
auto item = dynamic_cast<SmartPanelItem^>(button->DataContext);
auto contact = item->_contact;
RingD::instance->placeCall(contact);
}
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);
call->cancel();
}
void RingClientUWP::Views::SmartPanel::Grid_PointerEntered(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
auto grid = dynamic_cast<Grid^>(sender);
auto listBoxItem = dynamic_cast<ListBoxItem^>(sender);
auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext);
item->_callBar = Windows::UI::Xaml::Visibility::Visible;
}
void RingClientUWP::Views::SmartPanel::Grid_PointerExited(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
auto listBoxItem = dynamic_cast<ListBoxItem^>(sender);
auto grid = dynamic_cast<Grid^>(sender);
auto item = dynamic_cast<SmartPanelItem^>(grid->DataContext);
item->_callBar = Windows::UI::Xaml::Visibility::Collapsed;
}
void RingClientUWP::Views::SmartPanel::_contactItem__PointerReleased(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
auto listBoxItem = dynamic_cast<ListBoxItem^>(sender);
auto smartPanelItem = dynamic_cast<SmartPanelItem^>(listBoxItem->DataContext);
if (_smartList_->SelectedItem != smartPanelItem)
_smartList_->SelectedItem = smartPanelItem;
else
_smartList_->SelectedItem = nullptr;
}
\ No newline at end of file
......@@ -58,6 +58,11 @@ private:
void _ringTxtBx__KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e);
void _rejectIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void _acceptIncomingCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void _callContact__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void _cancelCallBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void Grid_PointerEntered(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e);
void Grid_PointerExited(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e);
void _contactItem__PointerReleased(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e);
/* members */
Vector<Controls::SmartPanelItem^>^ smartPanelItemsList_;
......
......@@ -42,5 +42,4 @@ SmartPanelItem::NotifyPropertyChanged(String^ propertyName)
{
PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
}));
}
}
\ No newline at end of file
......@@ -31,8 +31,31 @@ public:
SmartPanelItem();
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()
......@@ -62,6 +85,8 @@ protected:
void NotifyPropertyChanged(String^ propertyName);
private:
Visibility incomingCallBar_ = Visibility::Collapsed;
Visibility outGoingCallBar_ = Visibility::Collapsed;
Visibility callBar_ = Visibility::Collapsed;
Call^ call_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment