MainPage.xaml.cpp 15.1 KB
Newer Older
Nicolas Jager's avatar
Nicolas Jager committed
1
2
3
/**************************************************************************
* Copyright (C) 2016 by Savoir-faire Linux                                *
* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com>              *
atraczyk's avatar
atraczyk committed
4
* Author: Traczyk Andreas <andreas.traczyk@savoirfairelinux.com>          *
Nicolas Jager's avatar
Nicolas Jager committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*                                                                         *
* This program is free software; you can redistribute it and/or modify    *
* it under the terms of the GNU General Public License as published by    *
* the Free Software Foundation; either version 3 of the License, or       *
* (at your option) any later version.                                     *
*                                                                         *
* This program is distributed in the hope that it will be useful,         *
* but WITHOUT ANY WARRANTY; without even the implied warranty of          *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
* GNU General Public License for more details.                            *
*                                                                         *
* You should have received a copy of the GNU General Public License       *
* along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
**************************************************************************/
#include "pch.h"

Nicolas Jager's avatar
Nicolas Jager committed
21
22
#include "ContactsViewModel.h"
#include "MessageTextPage.xaml.h"
Nicolas Jager's avatar
Nicolas Jager committed
23
24
#include "SmartPanel.xaml.h"
#include "RingConsolePanel.xaml.h"
Nicolas Jager's avatar
Nicolas Jager committed
25
#include "VideoPage.xaml.h"
26
#include "PreviewPage.xaml.h"
Nicolas Jager's avatar
Nicolas Jager committed
27
28
29
30
31
32
#include "WelcomePage.xaml.h"

#include "MainPage.xaml.h"

using namespace RingClientUWP;
using namespace RingClientUWP::Views;
Nicolas Jager's avatar
Nicolas Jager committed
33
using namespace RingClientUWP::ViewModel;
Nicolas Jager's avatar
Nicolas Jager committed
34
35

using namespace Platform;
Nicolas Jager's avatar
Nicolas Jager committed
36
using namespace Windows::ApplicationModel::Core;
Nicolas Jager's avatar
Nicolas Jager committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Graphics::Display;
using namespace Windows::System;
atraczyk's avatar
atraczyk committed
51
using namespace Concurrency;
atraczyk's avatar
atraczyk committed
52
using namespace Windows::System::Threading;
Nicolas Jager's avatar
Nicolas Jager committed
53
54
55
56
57

MainPage::MainPage()
{
    InitializeComponent();

atraczyk's avatar
atraczyk committed
58
    UserModel::instance->getUserData();
59

60
61
    Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &MainPage::OnResize);

Nicolas Jager's avatar
Nicolas Jager committed
62
63
64
    _welcomeFrame_->Navigate(TypeName(RingClientUWP::Views::WelcomePage::typeid));
    _smartPanel_->Navigate(TypeName(RingClientUWP::Views::SmartPanel::typeid));
    _consolePanel_->Navigate(TypeName(RingClientUWP::Views::RingConsolePanel::typeid));
Nicolas Jager's avatar
Nicolas Jager committed
65
    _videoFrame_->Navigate(TypeName(RingClientUWP::Views::VideoPage::typeid));
66
    _previewFrame_->Navigate(TypeName(RingClientUWP::Views::PreviewPage::typeid));
Nicolas Jager's avatar
Nicolas Jager committed
67
68
69
    _messageTextFrame_->Navigate(TypeName(RingClientUWP::Views::MessageTextPage::typeid));

    /* connect to delegates */
Nicolas Jager's avatar
Nicolas Jager committed
70
71
72
73
    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);
74
75
    smartPanel->summonPreviewPage += ref new RingClientUWP::SummonPreviewPage(this, &RingClientUWP::MainPage::OnsummonPreviewPage);
    smartPanel->hidePreviewPage += ref new RingClientUWP::HidePreviewPage(this, &RingClientUWP::MainPage::OnhidePreviewPage);
Nicolas Jager's avatar
Nicolas Jager committed
76
77
78
    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);
79
80
81
    auto messageTextFrame = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);
    messageTextFrame->closeMessageTextPage += ref new RingClientUWP::CloseMessageTextPage(this, &RingClientUWP::MainPage::OncloseMessageTextPage);

atraczyk's avatar
atraczyk committed
82
    dpiChangedtoken = (DisplayInformation::GetForCurrentView()->DpiChanged += ref new TypedEventHandler<DisplayInformation^,
83
                       Platform::Object^>(this, &MainPage::DisplayProperties_DpiChanged));
84
85

    visibilityChangedEventToken = Window::Current->VisibilityChanged +=
Nicolas Jager's avatar
Nicolas Jager committed
86
                                      ref new WindowVisibilityChangedEventHandler(this, &MainPage::Application_VisibilityChanged);
atraczyk's avatar
atraczyk committed
87
88

    applicationSuspendingEventToken = Application::Current->Suspending +=
89
                                          ref new SuspendingEventHandler(this, &MainPage::Application_Suspending);
atraczyk's avatar
atraczyk committed
90
    applicationResumingEventToken = Application::Current->Resuming +=
91
                                        ref new EventHandler<Object^>(this, &MainPage::Application_Resuming);
atraczyk's avatar
atraczyk committed
92

93
94
    RingD::instance->registrationStateErrorGeneric += ref new RingClientUWP::RegistrationStateErrorGeneric(this, &RingClientUWP::MainPage::OnregistrationStateErrorGeneric);
    RingD::instance->registrationStateRegistered += ref new RingClientUWP::RegistrationStateRegistered(this, &RingClientUWP::MainPage::OnregistrationStateRegistered);
95
    RingD::instance->callPlaced += ref new RingClientUWP::CallPlaced(this, &RingClientUWP::MainPage::OncallPlaced);
96

Nicolas Jager's avatar
Nicolas Jager committed
97
    RingD::instance->setLoadingStatusText += ref new SetLoadingStatusText([this](String^ statusText, String^ color) {
98
99
100
101
102
        _loadingStatus_->Text = statusText;
        auto col = Utils::ColorFromString(color);
        auto brush = ref new Windows::UI::Xaml::Media::SolidColorBrush(col);
        _loadingStatus_->Foreground = brush;
    });
Nicolas Jager's avatar
Nicolas Jager committed
103
104
105
106
107
108
109
110
111
}

void
MainPage::OnKeyDown(KeyRoutedEventArgs^ e)
{
    if (e->Key == VirtualKey::F5) {
        _outerSplitView_->OpenPaneLength = Window::Current->Bounds.Width;
        _outerSplitView_->IsPaneOpen = !_outerSplitView_->IsPaneOpen;
    }
Nicolas Jager's avatar
Nicolas Jager committed
112
113
114
115
116
}

void RingClientUWP::MainPage::_toggleSmartBoxButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    _innerSplitView_->IsPaneOpen = !_innerSplitView_->IsPaneOpen;
117
118
119
120
121
122
123
124
    if (_innerSplitView_->IsPaneOpen) {
        dynamic_cast<SmartPanel^>(_smartPanel_->Content)->setMode(Views::SmartPanel::Mode::Normal);
        _hamburgerButtonBar_->Width = 320;
    }
    else {
        dynamic_cast<SmartPanel^>(_smartPanel_->Content)->setMode(Views::SmartPanel::Mode::Minimized);
        _hamburgerButtonBar_->Width = 60;
    }
Nicolas Jager's avatar
Nicolas Jager committed
125
}
Nicolas Jager's avatar
Nicolas Jager committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

void
RingClientUWP::MainPage::showFrame(Windows::UI::Xaml::Controls::Frame^ frame)
{
    _navGrid_->SetRow(_welcomeFrame_, 0);
    _navGrid_->SetRow(_messageTextFrame_, 0);
    _navGrid_->SetRow(_videoFrame_, 0);

    if (frame == _welcomeFrame_) {
        _navGrid_->SetRow(_welcomeFrame_, 1);
    } else if (frame == _videoFrame_) {
        _navGrid_->SetRow(_videoFrame_, 1);
    } else if (frame == _messageTextFrame_) {
        _navGrid_->SetRow(_messageTextFrame_, 1);
    }
}
142
143
144
145

void
RingClientUWP::MainPage::OnNavigatedTo(NavigationEventArgs ^ e)
{
atraczyk's avatar
atraczyk committed
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    auto iter = BackgroundTaskRegistration::AllTasks->First();
    auto hascur = iter->HasCurrent;
    while (hascur)
    {
        auto cur = iter->Current->Value;
        cur->Unregister(true);
        hascur = iter->MoveNext();
    }
    BackgroundExecutionManager::RequestAccessAsync();
    BackgroundTaskBuilder^ builder = ref new BackgroundTaskBuilder();
    builder->Name = "CallRefusalBackgroundTask";
    //builder->TaskEntryPoint = "RingClientUWP.BackgroundActivity";
    builder->SetTrigger(ref new ToastNotificationActionTrigger());
    BackgroundTaskRegistration^ registration = builder->Register();

161
    RingD::instance->init();
atraczyk's avatar
atraczyk committed
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    showLoadingOverlay(true, false);
}

void
RingClientUWP::MainPage::showLoadingOverlay(bool load, bool modal)
{
    if (!isLoading && load) {
        isLoading = true;
        _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Visible;
        if (modal) {
            _fadeInModalStoryboard_->Begin();
            auto blackBrush = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::Black);
            _loadingOverlayRect_->Fill = blackBrush;
        }
        else {
            auto whiteBrush = ref new Windows::UI::Xaml::Media::SolidColorBrush(Windows::UI::Colors::White);
            _loadingOverlayRect_->Fill = whiteBrush;
            _loadingOverlayRect_->Opacity = 1.0;
        }
    }
atraczyk's avatar
atraczyk committed
183
    else if (!load && isLoading) {
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
        isLoading = false;
        _fadeOutStoryboard_->Begin();
    }
}

void
RingClientUWP::MainPage::OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
}

void
RingClientUWP::MainPage::DisplayProperties_DpiChanged(DisplayInformation^ sender, Platform::Object^ args)
{
    OnResize(nullptr, nullptr);
}

void
RingClientUWP::MainPage::hideLoadingOverlay()
{
    _loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
Nicolas Jager's avatar
Nicolas Jager committed
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
}

void RingClientUWP::MainPage::OnsummonMessageTextPage()
{
    auto messageTextPage = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);
    messageTextPage->updatePageContent();
    showFrame(_messageTextFrame_);

}


void RingClientUWP::MainPage::OnsummonWelcomePage()
{
    showFrame(_welcomeFrame_);
}

220
221
void RingClientUWP::MainPage::OnsummonPreviewPage()
{
atraczyk's avatar
atraczyk committed
222
    MSG_("Show Settings Preview");
223
224
225
226
227
    _previewFrame_->Visibility = VIS::Visible;
}

void RingClientUWP::MainPage::OnhidePreviewPage()
{
atraczyk's avatar
atraczyk committed
228
    MSG_("Hide Settings Preview");
229
230
    _previewFrame_->Visibility = VIS::Collapsed;
}
Nicolas Jager's avatar
Nicolas Jager committed
231
232
233

void RingClientUWP::MainPage::OnsummonVideoPage()
{
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    auto item = SmartPanelItemsViewModel::instance->_selectedItem;
    auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);;

    if (item) {
        switch (item->_callStatus) {
        case CallStatus::IN_PROGRESS:
            videoPage->screenVideo(true);
            break;
        case CallStatus::PEER_PAUSED:
        case CallStatus::PAUSED:
            videoPage->screenVideo(false);
            break;
        }
    }

Nicolas Jager's avatar
Nicolas Jager committed
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    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 */
265
    case CallStatus::ENDED:
Nicolas Jager's avatar
Nicolas Jager committed
266
267
268
269
270
271
272
273
274
275
    {
        if (item)
            OnsummonMessageTextPage();
        break;
    }
    default:
        break;
    }

}
276

atraczyk's avatar
atraczyk committed
277
278
279
void
MainPage::Application_Suspending(Object^, Windows::ApplicationModel::SuspendingEventArgs^ e)
{
atraczyk's avatar
atraczyk committed
280
    MSG_("Application_Suspending");
atraczyk's avatar
atraczyk committed
281
    auto deferral = e->SuspendingOperation->GetDeferral();
atraczyk's avatar
atraczyk committed
282
    Video::VideoManager::instance->captureManager()->CleanupCameraAsync();
atraczyk's avatar
atraczyk committed
283
284
285
    MSG_("Hang up calls...");
    RingD::instance->deinit();
    deferral->Complete();
atraczyk's avatar
atraczyk committed
286
287
288
289
290
}

void
MainPage::Application_VisibilityChanged(Object^ sender, VisibilityChangedEventArgs^ e)
{
291
    auto vcm = Video::VideoManager::instance->captureManager();
292
    if (e->Visible) {
atraczyk's avatar
atraczyk committed
293
        MSG_("->Visible");
294
295
296
297
298
299
300
301
302
303
        bool isInCall = false;
        for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
            if (item->_callId && item->_callStatus == CallStatus::IN_PROGRESS) {
                isInCall = true;
                break;
            }
        }
        if (isInCall) {
            /*if (RingD::instance->currentCallId)
                RingD::instance->unPauseCall(RingD::instance->currentCallId);*/
304
305
306
307
308
            vcm->InitializeCameraAsync(false);
            vcm->videoFrameCopyInvoker->Start();
        }
        else if (vcm->isSettingsPreviewing) {
            vcm->CleanupCameraAsync()
Nicolas Jager's avatar
Nicolas Jager committed
309
            .then([=](task<void> cleanupCameraTask) {
310
311
312
313
314
315
316
317
318
319
320
                try {
                    cleanupCameraTask.get();
                    CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
                        CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
                    {
                        vcm->InitializeCameraAsync(true);
                    }));
                }
                catch (Exception^ e) {
                    WriteException(e);
                }
321
            });
322
        }
atraczyk's avatar
atraczyk committed
323
    }
324
    else {
atraczyk's avatar
atraczyk committed
325
        MSG_("->Invisible");
326
327
328
329
330
331
332
333
334
        bool isInCall = false;
        for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
            if (item->_callId && item->_callStatus == CallStatus::IN_PROGRESS) {
                isInCall = true;
                RingD::instance->currentCallId = item->_callId;
                break;
            }
        }
        if (isInCall) {
335
            // TODO
336
            /*if (RingD::instance->currentCallId) {
atraczyk's avatar
atraczyk committed
337
                MSG_("Pausing call: " + RingD::instance->currentCallId);
338
339
                RingD::instance->pauseCall(RingD::instance->currentCallId);
            }*/
340
341
342
343
344
            if (vcm->isPreviewing) {
                vcm->StopPreviewAsync();
                if (vcm->captureTaskTokenSource)
                    vcm->captureTaskTokenSource->cancel();
                vcm->videoFrameCopyInvoker->Stop();
345
346
            }
        }
347
348
349
        else if (vcm->isSettingsPreviewing) {
            vcm->StopPreviewAsync();
        }
atraczyk's avatar
atraczyk committed
350
    }
351
352
}

353
354
void MainPage::Application_Resuming(Object^, Object^)
{
atraczyk's avatar
atraczyk committed
355
    MSG_("Application_Resuming");
356
357
}

358
359
void RingClientUWP::MainPage::OncloseMessageTextPage()
{
360
361
    SmartPanelItemsViewModel::instance->_selectedItem = nullptr;
    showFrame(_welcomeFrame_);
362
}
363
364
365
366
367
368
369
370
371
372
373


void RingClientUWP::MainPage::OnregistrationStateErrorGeneric(const std::string& accountId)
{
    showLoadingOverlay(false, false);
}


void RingClientUWP::MainPage::OnregistrationStateRegistered()
{
    showLoadingOverlay(false, false);
Nicolas Jager's avatar
Nicolas Jager committed
374
375
376
377
378

    /* do not connect those delegates before initial registration on dht is fine.
       Otherwise your going to mess with the wizard */
    RingD::instance->nameRegistred += ref new RingClientUWP::NameRegistred(this, &RingClientUWP::MainPage::OnnameRegistred);
    RingD::instance->volatileDetailsChanged += ref new RingClientUWP::VolatileDetailsChanged(this, &RingClientUWP::MainPage::OnvolatileDetailsChanged);
379
}
380
381
382
383
384
385


void RingClientUWP::MainPage::OncallPlaced(Platform::String ^callId)
{
    showFrame(_welcomeFrame_);
}
Nicolas Jager's avatar
Nicolas Jager committed
386
387
388
389
390
391
392
393
394
395
396
397


void RingClientUWP::MainPage::OnnameRegistred(bool status)
{
    showLoadingOverlay(false, false);
}


void RingClientUWP::MainPage::OnvolatileDetailsChanged(const std::string &accountId, const std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string>>> &details)
{
    showLoadingOverlay(false, false);
}