MainPage.xaml.cpp 14.7 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
#include "WelcomePage.xaml.h"
atraczyk's avatar
atraczyk committed
28
#include "AboutPage.xaml.h"
Nicolas Jager's avatar
Nicolas Jager committed
29
30
31
32
33

#include "MainPage.xaml.h"

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

using namespace Platform;
Nicolas Jager's avatar
Nicolas Jager committed
37
using namespace Windows::ApplicationModel::Core;
Nicolas Jager's avatar
Nicolas Jager committed
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
52
using namespace Concurrency;
atraczyk's avatar
atraczyk committed
53
using namespace Windows::System::Threading;
Nicolas Jager's avatar
Nicolas Jager committed
54
55
56
57
58

MainPage::MainPage()
{
    InitializeComponent();

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

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

Nicolas Jager's avatar
Nicolas Jager committed
63
64
65
    _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
66
    _videoFrame_->Navigate(TypeName(RingClientUWP::Views::VideoPage::typeid));
67
    _previewFrame_->Navigate(TypeName(RingClientUWP::Views::PreviewPage::typeid));
Nicolas Jager's avatar
Nicolas Jager committed
68
69
70
    _messageTextFrame_->Navigate(TypeName(RingClientUWP::Views::MessageTextPage::typeid));

    /* connect to delegates */
Nicolas Jager's avatar
Nicolas Jager committed
71
72
73
74
    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);
75
76
    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
77
    smartPanel->summonVideoPage += ref new RingClientUWP::SummonVideoPage(this, &RingClientUWP::MainPage::OnsummonVideoPage);
atraczyk's avatar
atraczyk committed
78

Nicolas Jager's avatar
Nicolas Jager committed
79
80
    auto videoPage = dynamic_cast<VideoPage^>(_videoFrame_->Content);
    videoPage->pressHangUpCall += ref new RingClientUWP::PressHangUpCall(this, &RingClientUWP::MainPage::OnpressHangUpCall);
81
82
83
    auto messageTextFrame = dynamic_cast<MessageTextPage^>(_messageTextFrame_->Content);
    messageTextFrame->closeMessageTextPage += ref new RingClientUWP::CloseMessageTextPage(this, &RingClientUWP::MainPage::OncloseMessageTextPage);

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

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

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

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

Nicolas Jager's avatar
Nicolas Jager committed
99
    RingD::instance->setLoadingStatusText += ref new SetLoadingStatusText([this](String^ statusText, String^ color) {
100
101
102
103
104
        _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
105
106
107
108
109
110
111
112
113
}

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
114
115
116
117
118
}

void RingClientUWP::MainPage::_toggleSmartBoxButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    _innerSplitView_->IsPaneOpen = !_innerSplitView_->IsPaneOpen;
119
120
121
122
123
124
125
126
    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
127
}
Nicolas Jager's avatar
Nicolas Jager committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

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);
    }
}
144
145
146
147

void
RingClientUWP::MainPage::OnNavigatedTo(NavigationEventArgs ^ e)
{
atraczyk's avatar
atraczyk committed
148
149
150
151
    bool fromAboutPage = (e->Parameter != nullptr) ? safe_cast<bool>(e->Parameter) : false;
    if (!fromAboutPage) {
        RingD::instance->init();
        showLoadingOverlay(true, false);
atraczyk's avatar
atraczyk committed
152
    }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
}

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
172
    else if (!load && isLoading) {
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
        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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
}

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

}


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

209
210
void RingClientUWP::MainPage::OnsummonPreviewPage()
{
atraczyk's avatar
atraczyk committed
211
    MSG_("Show Settings Preview");
212
213
214
215
216
    _previewFrame_->Visibility = VIS::Visible;
}

void RingClientUWP::MainPage::OnhidePreviewPage()
{
atraczyk's avatar
atraczyk committed
217
    MSG_("Hide Settings Preview");
218
219
    _previewFrame_->Visibility = VIS::Collapsed;
}
Nicolas Jager's avatar
Nicolas Jager committed
220
221
222

void RingClientUWP::MainPage::OnsummonVideoPage()
{
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    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 */
254
    case CallStatus::ENDED:
Nicolas Jager's avatar
Nicolas Jager committed
255
256
257
258
259
260
261
262
263
264
    {
        if (item)
            OnsummonMessageTextPage();
        break;
    }
    default:
        break;
    }

}
265

atraczyk's avatar
atraczyk committed
266
267
268
void
MainPage::Application_Suspending(Object^, Windows::ApplicationModel::SuspendingEventArgs^ e)
{
atraczyk's avatar
atraczyk committed
269
    MSG_("Application_Suspending");
atraczyk's avatar
atraczyk committed
270
    auto deferral = e->SuspendingOperation->GetDeferral();
atraczyk's avatar
atraczyk committed
271
    Video::VideoManager::instance->captureManager()->CleanupCameraAsync();
atraczyk's avatar
atraczyk committed
272
273
274
    MSG_("Hang up calls...");
    RingD::instance->deinit();
    deferral->Complete();
atraczyk's avatar
atraczyk committed
275
276
277
278
279
}

void
MainPage::Application_VisibilityChanged(Object^ sender, VisibilityChangedEventArgs^ e)
{
280
    auto vcm = Video::VideoManager::instance->captureManager();
281
    if (e->Visible) {
atraczyk's avatar
atraczyk committed
282
        MSG_("->Visible");
283
284
285
286
287
288
289
290
291
292
        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);*/
293
294
295
296
297
            vcm->InitializeCameraAsync(false);
            vcm->videoFrameCopyInvoker->Start();
        }
        else if (vcm->isSettingsPreviewing) {
            vcm->CleanupCameraAsync()
Nicolas Jager's avatar
Nicolas Jager committed
298
            .then([=](task<void> cleanupCameraTask) {
299
300
301
302
303
304
305
306
307
308
309
                try {
                    cleanupCameraTask.get();
                    CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
                        CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
                    {
                        vcm->InitializeCameraAsync(true);
                    }));
                }
                catch (Exception^ e) {
                    WriteException(e);
                }
310
            });
311
        }
atraczyk's avatar
atraczyk committed
312
    }
313
    else {
atraczyk's avatar
atraczyk committed
314
        MSG_("->Invisible");
315
316
317
318
319
320
321
322
323
        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) {
324
            // TODO
325
            /*if (RingD::instance->currentCallId) {
atraczyk's avatar
atraczyk committed
326
                MSG_("Pausing call: " + RingD::instance->currentCallId);
327
328
                RingD::instance->pauseCall(RingD::instance->currentCallId);
            }*/
329
330
331
332
333
            if (vcm->isPreviewing) {
                vcm->StopPreviewAsync();
                if (vcm->captureTaskTokenSource)
                    vcm->captureTaskTokenSource->cancel();
                vcm->videoFrameCopyInvoker->Stop();
334
335
            }
        }
336
337
338
        else if (vcm->isSettingsPreviewing) {
            vcm->StopPreviewAsync();
        }
atraczyk's avatar
atraczyk committed
339
    }
340
341
}

342
343
void MainPage::Application_Resuming(Object^, Object^)
{
atraczyk's avatar
atraczyk committed
344
    MSG_("Application_Resuming");
345
346
}

347
348
void RingClientUWP::MainPage::OncloseMessageTextPage()
{
349
350
    SmartPanelItemsViewModel::instance->_selectedItem = nullptr;
    showFrame(_welcomeFrame_);
351
}
352
353
354
355
356
357
358
359
360
361
362


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
363
364
365
366
367

    /* 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);
368
}
369
370
371
372
373
374


void RingClientUWP::MainPage::OncallPlaced(Platform::String ^callId)
{
    showFrame(_welcomeFrame_);
}
Nicolas Jager's avatar
Nicolas Jager committed
375
376
377
378
379
380
381
382
383
384
385
386


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);
}