blob: 99e016d9dd19d7df66b72a853e3447b42bb1b5cc [file] [log] [blame]
Nicolas Jager998fbd72016-08-08 11:41:28 -04001/**************************************************************************
2* Copyright (C) 2016 by Savoir-faire Linux *
3* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> *
atraczyk6cae7a62016-11-30 14:56:31 -05004* Author: Traczyk Andreas <andreas.traczyk@savoirfairelinux.com> *
Nicolas Jager998fbd72016-08-08 11:41:28 -04005* *
6* This program is free software; you can redistribute it and/or modify *
7* it under the terms of the GNU General Public License as published by *
8* the Free Software Foundation; either version 3 of the License, or *
9* (at your option) any later version. *
10* *
11* This program is distributed in the hope that it will be useful, *
12* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14* GNU General Public License for more details. *
15* *
16* You should have received a copy of the GNU General Public License *
17* along with this program. If not, see <http://www.gnu.org/licenses/>. *
18**************************************************************************/
19#include "pch.h"
20
Nicolas Jager8a85e1f2016-08-15 15:11:06 -040021#include "ContactsViewModel.h"
22#include "MessageTextPage.xaml.h"
Nicolas Jager998fbd72016-08-08 11:41:28 -040023#include "SmartPanel.xaml.h"
24#include "RingConsolePanel.xaml.h"
Nicolas Jagere069c412016-08-15 15:00:17 -040025#include "VideoPage.xaml.h"
atraczykacc4c412016-11-10 22:56:52 -050026#include "PreviewPage.xaml.h"
Nicolas Jager998fbd72016-08-08 11:41:28 -040027#include "WelcomePage.xaml.h"
28
29#include "MainPage.xaml.h"
30
31using namespace RingClientUWP;
32using namespace RingClientUWP::Views;
Nicolas Jager8a85e1f2016-08-15 15:11:06 -040033using namespace RingClientUWP::ViewModel;
Nicolas Jager998fbd72016-08-08 11:41:28 -040034
35using namespace Platform;
Nicolas Jager15861202016-08-12 11:13:05 -040036using namespace Windows::ApplicationModel::Core;
Nicolas Jager998fbd72016-08-08 11:41:28 -040037using namespace Windows::Foundation;
38using namespace Windows::Foundation::Collections;
39using namespace Windows::UI::ViewManagement;
40using namespace Windows::UI::Xaml;
41using namespace Windows::UI::Xaml::Controls;
42using namespace Windows::UI::Xaml::Controls::Primitives;
43using namespace Windows::UI::Core;
44using namespace Windows::UI::Xaml::Data;
45using namespace Windows::UI::Xaml::Input;
46using namespace Windows::UI::Xaml::Interop;
Nicolas Jager998fbd72016-08-08 11:41:28 -040047using namespace Windows::UI::Xaml::Navigation;
48using namespace Windows::ApplicationModel::Activation;
49using namespace Windows::Graphics::Display;
50using namespace Windows::System;
atraczyk49f1b572016-10-27 12:33:28 -040051using namespace Concurrency;
atraczyk6cae7a62016-11-30 14:56:31 -050052using namespace Windows::System::Threading;
Nicolas Jager998fbd72016-08-08 11:41:28 -040053
54MainPage::MainPage()
55{
56 InitializeComponent();
57
atraczykaeb4a5c2016-12-01 19:17:18 -050058 ApplicationView::GetForCurrentView()->TryResizeView(Size(1024, 768));
59
atraczyk49f1b572016-10-27 12:33:28 -040060 UserModel::instance->getUserData();
Nicolas Jagerdf0a0672016-10-18 09:25:37 -040061
atraczyk1ddcb5a2016-09-07 16:18:30 -040062 Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &MainPage::OnResize);
63
Nicolas Jager998fbd72016-08-08 11:41:28 -040064 _welcomeFrame_->Navigate(TypeName(RingClientUWP::Views::WelcomePage::typeid));
65 _smartPanel_->Navigate(TypeName(RingClientUWP::Views::SmartPanel::typeid));
66 _consolePanel_->Navigate(TypeName(RingClientUWP::Views::RingConsolePanel::typeid));
Nicolas Jagere069c412016-08-15 15:00:17 -040067 _videoFrame_->Navigate(TypeName(RingClientUWP::Views::VideoPage::typeid));
atraczykacc4c412016-11-10 22:56:52 -050068 _previewFrame_->Navigate(TypeName(RingClientUWP::Views::PreviewPage::typeid));
Nicolas Jager8a85e1f2016-08-15 15:11:06 -040069 _messageTextFrame_->Navigate(TypeName(RingClientUWP::Views::MessageTextPage::typeid));
70
71 /* connect to delegates */
Nicolas Jagerc551c362016-10-01 19:24:50 -040072 RingD::instance->stateChange += ref new RingClientUWP::StateChange(this, &RingClientUWP::MainPage::OnstateChange);
73 auto smartPanel = dynamic_cast<SmartPanel^>(_smartPanel_->Content);
74 smartPanel->summonMessageTextPage += ref new RingClientUWP::SummonMessageTextPage(this, &RingClientUWP::MainPage::OnsummonMessageTextPage);
75 smartPanel->summonWelcomePage += ref new RingClientUWP::SummonWelcomePage(this, &RingClientUWP::MainPage::OnsummonWelcomePage);
atraczykacc4c412016-11-10 22:56:52 -050076 smartPanel->summonPreviewPage += ref new RingClientUWP::SummonPreviewPage(this, &RingClientUWP::MainPage::OnsummonPreviewPage);
77 smartPanel->hidePreviewPage += ref new RingClientUWP::HidePreviewPage(this, &RingClientUWP::MainPage::OnhidePreviewPage);
Nicolas Jagerc551c362016-10-01 19:24:50 -040078 smartPanel->summonVideoPage += ref new RingClientUWP::SummonVideoPage(this, &RingClientUWP::MainPage::OnsummonVideoPage);
79 auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);
80 videoPage->pressHangUpCall += ref new RingClientUWP::PressHangUpCall(this, &RingClientUWP::MainPage::OnpressHangUpCall);
Nicolas Jagere72856b2016-10-30 15:06:17 -040081 auto messageTextFrame = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);
82 messageTextFrame->closeMessageTextPage += ref new RingClientUWP::CloseMessageTextPage(this, &RingClientUWP::MainPage::OncloseMessageTextPage);
83
atraczyk6cae7a62016-11-30 14:56:31 -050084 dpiChangedtoken = (DisplayInformation::GetForCurrentView()->DpiChanged += ref new TypedEventHandler<DisplayInformation^,
Nicolas Jager7bef1492016-09-14 11:23:29 -040085 Platform::Object^>(this, &MainPage::DisplayProperties_DpiChanged));
atraczyk6290cc32016-10-07 08:47:15 -040086
87 visibilityChangedEventToken = Window::Current->VisibilityChanged +=
Nicolas Jager598aee22016-11-14 09:32:02 -050088 ref new WindowVisibilityChangedEventHandler(this, &MainPage::Application_VisibilityChanged);
atraczyk6cae7a62016-11-30 14:56:31 -050089
90 applicationSuspendingEventToken = Application::Current->Suspending +=
Nicolas Jagercba46f72016-12-02 16:04:50 -050091 ref new SuspendingEventHandler(this, &MainPage::Application_Suspending);
atraczyk6cae7a62016-11-30 14:56:31 -050092 applicationResumingEventToken = Application::Current->Resuming +=
Nicolas Jagercba46f72016-12-02 16:04:50 -050093 ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);
atraczyk6cae7a62016-11-30 14:56:31 -050094
Nicolas Jager026a84b2016-11-28 10:58:22 -050095 RingD::instance->registrationStateErrorGeneric += ref new RingClientUWP::RegistrationStateErrorGeneric(this, &RingClientUWP::MainPage::OnregistrationStateErrorGeneric);
96 RingD::instance->registrationStateRegistered += ref new RingClientUWP::RegistrationStateRegistered(this, &RingClientUWP::MainPage::OnregistrationStateRegistered);
Nicolas Jagercba46f72016-12-02 16:04:50 -050097 RingD::instance->callPlaced += ref new RingClientUWP::CallPlaced(this, &RingClientUWP::MainPage::OncallPlaced);
Nicolas Jager998fbd72016-08-08 11:41:28 -040098}
99
100void
101MainPage::OnKeyDown(KeyRoutedEventArgs^ e)
102{
103 if (e->Key == VirtualKey::F5) {
104 _outerSplitView_->OpenPaneLength = Window::Current->Bounds.Width;
105 _outerSplitView_->IsPaneOpen = !_outerSplitView_->IsPaneOpen;
106 }
Nicolas Jager15861202016-08-12 11:13:05 -0400107}
108
109void RingClientUWP::MainPage::_toggleSmartBoxButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
110{
111 _innerSplitView_->IsPaneOpen = !_innerSplitView_->IsPaneOpen;
atraczyk0cf42d72016-09-06 11:16:37 -0400112 if (_innerSplitView_->IsPaneOpen) {
113 dynamic_cast<SmartPanel^>(_smartPanel_->Content)->setMode(Views::SmartPanel::Mode::Normal);
114 _hamburgerButtonBar_->Width = 320;
115 }
116 else {
117 dynamic_cast<SmartPanel^>(_smartPanel_->Content)->setMode(Views::SmartPanel::Mode::Minimized);
118 _hamburgerButtonBar_->Width = 60;
119 }
Nicolas Jager15861202016-08-12 11:13:05 -0400120}
Nicolas Jager8a85e1f2016-08-15 15:11:06 -0400121
122void
123RingClientUWP::MainPage::showFrame(Windows::UI::Xaml::Controls::Frame^ frame)
124{
125 _navGrid_->SetRow(_welcomeFrame_, 0);
126 _navGrid_->SetRow(_messageTextFrame_, 0);
127 _navGrid_->SetRow(_videoFrame_, 0);
128
129 if (frame == _welcomeFrame_) {
130 _navGrid_->SetRow(_welcomeFrame_, 1);
131 } else if (frame == _videoFrame_) {
132 _navGrid_->SetRow(_videoFrame_, 1);
133 } else if (frame == _messageTextFrame_) {
134 _navGrid_->SetRow(_messageTextFrame_, 1);
Nicolas Jager8a85e1f2016-08-15 15:11:06 -0400135 }
136}
atraczyk61b28422016-08-24 09:25:59 -0400137
138void
139RingClientUWP::MainPage::OnNavigatedTo(NavigationEventArgs ^ e)
140{
atraczyk9e71a6b2016-11-18 17:00:15 -0500141 RingD::instance->init();
atraczyk1ddcb5a2016-09-07 16:18:30 -0400142 showLoadingOverlay(true, false);
143}
144
145void
146RingClientUWP::MainPage::showLoadingOverlay(bool load, bool modal)
147{
148 if (!isLoading && load) {
149 isLoading = true;
150 _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Visible;
151 if (modal) {
152 _fadeInModalStoryboard_->Begin();
153 auto blackBrush = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::Black);
154 _loadingOverlayRect_->Fill = blackBrush;
155 }
156 else {
157 auto whiteBrush = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::White);
158 _loadingOverlayRect_->Fill = whiteBrush;
159 _loadingOverlayRect_->Opacity = 1.0;
160 }
atraczyk6cae7a62016-11-30 14:56:31 -0500161 TimeSpan delay;
atraczykaeb4a5c2016-12-01 19:17:18 -0500162 delay.Duration = 10000 * 50;
atraczyk6cae7a62016-11-30 14:56:31 -0500163 ThreadPoolTimer^ delayTimer = ThreadPoolTimer::CreateTimer(
Nicolas Jagercba46f72016-12-02 16:04:50 -0500164 ref new TimerElapsedHandler([this](ThreadPoolTimer^ source)
atraczyk6cae7a62016-11-30 14:56:31 -0500165 {
166 Dispatcher->RunAsync(CoreDispatcherPriority::High,
Nicolas Jagercba46f72016-12-02 16:04:50 -0500167 ref new DispatchedHandler([this]()
atraczyk6cae7a62016-11-30 14:56:31 -0500168 {
169 OnResize(nullptr, nullptr);
170 }));
171 }), delay);
atraczyk1ddcb5a2016-09-07 16:18:30 -0400172 }
atraczykaeb4a5c2016-12-01 19:17:18 -0500173 else if (!load && isLoading) {
atraczyk1ddcb5a2016-09-07 16:18:30 -0400174 isLoading = false;
175 _fadeOutStoryboard_->Begin();
176 }
177}
178
179void
180RingClientUWP::MainPage::PositionImage()
181{
182 bounds = ApplicationView::GetForCurrentView()->VisibleBounds;
183
184 auto img = ref new Image();
185 auto bitmapImage = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
186 Windows::Foundation::Uri^ uri;
187
atraczyk1ddcb5a2016-09-07 16:18:30 -0400188 _loadingImage_->SetValue(Canvas::LeftProperty, bounds.Width * 0.5 - _loadingImage_->Width * 0.5);
189 _loadingImage_->SetValue(Canvas::TopProperty, bounds.Height * 0.5 - _loadingImage_->Height * 0.5);
190}
191
192void
193RingClientUWP::MainPage::PositionRing()
194{
195 double left;
196 double top;
atraczyk6cae7a62016-11-30 14:56:31 -0500197
198 _splashProgressRing_->Width = 144;
199 _splashProgressRing_->Height = 144;
200
201 left = bounds.Width * 0.5 - _loadingImage_->Width * 0.5 + 139;
202 top = bounds.Height * 0.5 - _loadingImage_->Height * 0.5 + 78;
203
204 _splashProgressRing_->SetValue(Canvas::LeftProperty, left);
205 _splashProgressRing_->SetValue(Canvas::TopProperty, top);
atraczyk1ddcb5a2016-09-07 16:18:30 -0400206}
207
208void
209RingClientUWP::MainPage::OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
210{
atraczyk6cae7a62016-11-30 14:56:31 -0500211 Dispatcher->RunAsync(CoreDispatcherPriority::High,
212 ref new DispatchedHandler([this]()
213 {
214 PositionImage();
215 PositionRing();
216 }));
atraczyk1ddcb5a2016-09-07 16:18:30 -0400217}
218
219void
220RingClientUWP::MainPage::DisplayProperties_DpiChanged(DisplayInformation^ sender, Platform::Object^ args)
221{
222 OnResize(nullptr, nullptr);
223}
224
225void
226RingClientUWP::MainPage::hideLoadingOverlay()
227{
228 _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
Nicolas Jagerc551c362016-10-01 19:24:50 -0400229}
230
231void RingClientUWP::MainPage::OnsummonMessageTextPage()
232{
233 auto messageTextPage = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);
234 messageTextPage->updatePageContent();
235 showFrame(_messageTextFrame_);
236
237}
238
239
240void RingClientUWP::MainPage::OnsummonWelcomePage()
241{
242 showFrame(_welcomeFrame_);
243}
244
atraczykacc4c412016-11-10 22:56:52 -0500245void RingClientUWP::MainPage::OnsummonPreviewPage()
246{
atraczykc25f69d2016-11-22 19:55:16 -0500247 MSG_("Show Settings Preview");
atraczykacc4c412016-11-10 22:56:52 -0500248 _previewFrame_->Visibility = VIS::Visible;
249}
250
251void RingClientUWP::MainPage::OnhidePreviewPage()
252{
atraczykc25f69d2016-11-22 19:55:16 -0500253 MSG_("Hide Settings Preview");
atraczykacc4c412016-11-10 22:56:52 -0500254 _previewFrame_->Visibility = VIS::Collapsed;
255}
Nicolas Jagerc551c362016-10-01 19:24:50 -0400256
257void RingClientUWP::MainPage::OnsummonVideoPage()
258{
Nicolas Jagercba46f72016-12-02 16:04:50 -0500259 auto item = SmartPanelItemsViewModel::instance->_selectedItem;
260 auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);;
261
262 if (item) {
263 switch (item->_callStatus) {
264 case CallStatus::IN_PROGRESS:
265 videoPage->screenVideo(true);
266 break;
267 case CallStatus::PEER_PAUSED:
268 case CallStatus::PAUSED:
269 videoPage->screenVideo(false);
270 break;
271 }
272 }
273
Nicolas Jager63447442016-11-28 23:27:41 -0500274 videoPage->chatOpen = false;
Nicolas Jagerc551c362016-10-01 19:24:50 -0400275 videoPage->updatePageContent();
276 showFrame(_videoFrame_);
277}
278
279
280void RingClientUWP::MainPage::OnpressHangUpCall()
281{
282 OnsummonMessageTextPage();
283}
284
Nicolas Jagerc551c362016-10-01 19:24:50 -0400285void RingClientUWP::MainPage::OnstateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code)
286{
287 auto item = SmartPanelItemsViewModel::instance->_selectedItem;
288
289 switch (state) {
290 /* send the user to the peer's message text page */
atraczyk85e12312016-11-03 10:31:23 -0400291 case CallStatus::ENDED:
Nicolas Jagerc551c362016-10-01 19:24:50 -0400292 {
293 if (item)
294 OnsummonMessageTextPage();
295 break;
296 }
Nicolas Jagerc551c362016-10-01 19:24:50 -0400297 default:
298 break;
299 }
300
301}
atraczykacc4c412016-11-10 22:56:52 -0500302
atraczyk14ba30c2016-09-22 18:31:59 -0400303void
304MainPage::Application_Suspending(Object^, Windows::ApplicationModel::SuspendingEventArgs^ e)
305{
atraczykc25f69d2016-11-22 19:55:16 -0500306 MSG_("Application_Suspending");
atraczyk6cae7a62016-11-30 14:56:31 -0500307 auto deferral = e->SuspendingOperation->GetDeferral();
atraczyk890921f2016-12-02 16:26:31 -0500308 Video::VideoManager::instance->captureManager()->CleanupCameraAsync();
atraczyk6cae7a62016-11-30 14:56:31 -0500309 MSG_("Hang up calls...");
310 RingD::instance->deinit();
311 deferral->Complete();
atraczyk14ba30c2016-09-22 18:31:59 -0400312}
313
314void
315MainPage::Application_VisibilityChanged(Object^ sender, VisibilityChangedEventArgs^ e)
316{
atraczykacc4c412016-11-10 22:56:52 -0500317 auto vcm = Video::VideoManager::instance->captureManager();
atraczyk6290cc32016-10-07 08:47:15 -0400318 if (e->Visible) {
atraczykc25f69d2016-11-22 19:55:16 -0500319 MSG_("->Visible");
atraczykc8f949a2016-10-07 11:34:03 -0400320 bool isInCall = false;
321 for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
322 if (item->_callId && item->_callStatus == CallStatus::IN_PROGRESS) {
323 isInCall = true;
324 break;
325 }
326 }
327 if (isInCall) {
328 /*if (RingD::instance->currentCallId)
329 RingD::instance->unPauseCall(RingD::instance->currentCallId);*/
atraczykacc4c412016-11-10 22:56:52 -0500330 vcm->InitializeCameraAsync(false);
331 vcm->videoFrameCopyInvoker->Start();
332 }
333 else if (vcm->isSettingsPreviewing) {
334 vcm->CleanupCameraAsync()
Nicolas Jagera4d062a2016-11-23 13:29:44 -0500335 .then([=](task<void> cleanupCameraTask) {
atraczyk9e71a6b2016-11-18 17:00:15 -0500336 try {
337 cleanupCameraTask.get();
338 CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
339 CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
340 {
341 vcm->InitializeCameraAsync(true);
342 }));
343 }
344 catch (Exception^ e) {
345 WriteException(e);
346 }
atraczykacc4c412016-11-10 22:56:52 -0500347 });
atraczykc8f949a2016-10-07 11:34:03 -0400348 }
atraczyk14ba30c2016-09-22 18:31:59 -0400349 }
atraczyk6290cc32016-10-07 08:47:15 -0400350 else {
atraczykc25f69d2016-11-22 19:55:16 -0500351 MSG_("->Invisible");
atraczykc8f949a2016-10-07 11:34:03 -0400352 bool isInCall = false;
353 for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
354 if (item->_callId && item->_callStatus == CallStatus::IN_PROGRESS) {
355 isInCall = true;
356 RingD::instance->currentCallId = item->_callId;
357 break;
358 }
359 }
360 if (isInCall) {
atraczykacc4c412016-11-10 22:56:52 -0500361 // TODO
atraczykc8f949a2016-10-07 11:34:03 -0400362 /*if (RingD::instance->currentCallId) {
atraczykc25f69d2016-11-22 19:55:16 -0500363 MSG_("Pausing call: " + RingD::instance->currentCallId);
atraczykc8f949a2016-10-07 11:34:03 -0400364 RingD::instance->pauseCall(RingD::instance->currentCallId);
365 }*/
atraczykacc4c412016-11-10 22:56:52 -0500366 if (vcm->isPreviewing) {
367 vcm->StopPreviewAsync();
368 if (vcm->captureTaskTokenSource)
369 vcm->captureTaskTokenSource->cancel();
370 vcm->videoFrameCopyInvoker->Stop();
atraczykc8f949a2016-10-07 11:34:03 -0400371 }
372 }
atraczykacc4c412016-11-10 22:56:52 -0500373 else if (vcm->isSettingsPreviewing) {
374 vcm->StopPreviewAsync();
375 }
atraczyk14ba30c2016-09-22 18:31:59 -0400376 }
Nicolas Jager083b3ae2016-10-04 08:46:19 -0400377}
378
atraczyk6290cc32016-10-07 08:47:15 -0400379void MainPage::Application_Resuming(Object^, Object^)
380{
atraczykc25f69d2016-11-22 19:55:16 -0500381 MSG_("Application_Resuming");
atraczyk6290cc32016-10-07 08:47:15 -0400382}
383
Nicolas Jagere72856b2016-10-30 15:06:17 -0400384void RingClientUWP::MainPage::OncloseMessageTextPage()
385{
386 auto smartPanel = dynamic_cast<SmartPanel^>(_smartPanel_->Content);
387 smartPanel->unselectContact();
388}
Nicolas Jager026a84b2016-11-28 10:58:22 -0500389
390
391void RingClientUWP::MainPage::OnregistrationStateErrorGeneric(const std::string& accountId)
392{
393 showLoadingOverlay(false, false);
394}
395
396
397void RingClientUWP::MainPage::OnregistrationStateRegistered()
398{
399 showLoadingOverlay(false, false);
400}
Nicolas Jagercba46f72016-12-02 16:04:50 -0500401
402
403void RingClientUWP::MainPage::OncallPlaced(Platform::String ^callId)
404{
405 showFrame(_welcomeFrame_);
406}