Commit 1ddcb5a6 authored by atraczyk's avatar atraczyk

UI/accounts: adds a loading screen during account loading

- adds faded loading pages with a spinner animation
- starts and stops the load page during account creation and loading
- resizes the loading graphics when window is resized
- adds an event handler for DPI and scale factor changes
- removes stretching from welcome page image
- clears account creation alias box after account creation clicked

Change-Id: I5046e0bc820e91c8b2f91ca223534d93ddf916f1
Tuleap: #1010
parent c52e6edd
<!-- **********************************************************************
* Copyright (C) 2016 by Savoir-faire Linux *
* Author: Jäger Nicolas<nicolas.jager@savoirfairelinux.com> *
* Author: Traczyk Andreas<andreas.traczyk@savoirfairelinux.com> *
* *
* 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 *
......@@ -23,18 +24,57 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<Storyboard x:Name="_fadeOutStoryboard_">
<DoubleAnimation
Storyboard.TargetName="_loadingOverlay_"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:1" Completed="hideLoadingOverlay"/>
</Storyboard>
<Storyboard x:Name="_fadeInModalStoryboard_">
<DoubleAnimation
Storyboard.TargetName="_loadingOverlay_"
Storyboard.TargetProperty="Opacity"
From="0.0" To="0.85" Duration="0:0:0.25"/>
</Storyboard>
</Page.Resources>
<Grid>
<Grid x:Name="_loadingOverlay_"
Canvas.ZIndex="4"
Visibility="Collapsed">
<Rectangle x:Name="_loadingOverlayRect_"
Canvas.ZIndex="5"
Fill="Black"
Opacity="0.85"
Width="auto"
Height="auto">
</Rectangle>
<Canvas Canvas.ZIndex="6">
<Image x:Name="_loadingImage_"
Source="Assets/Tests/logo-ring.scale-100.png"
Width="620"
Height="300"/>
<ProgressRing Foreground="#19a0b7"
Name="_splashProgressRing_"
IsActive="True"
MaxWidth="200"
MaxHeight="200"
Width="118"
Height="118"/>
</Canvas>
</Grid>
<SplitView x:Name="_outerSplitView_"
IsPaneOpen="False">
<SplitView.Pane>
<Frame x:Name="_consolePanel_"/>
</SplitView.Pane>
<SplitView.Content>
<SplitView x:Name="_innerSplitView_"
<SplitView.Pane>
<Frame x:Name="_consolePanel_"/>
</SplitView.Pane>
<SplitView.Content>
<SplitView x:Name="_innerSplitView_"
IsPaneOpen="True"
CompactPaneLength="60"
DisplayMode="CompactInline">
<SplitView.Pane>
<SplitView.Pane>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
......@@ -62,7 +102,7 @@
</Frame>
</Grid>
</SplitView.Pane>
<SplitView.Content>
<SplitView.Content>
<Grid x:Name="_navGrid_">
<Grid.RowDefinitions>
<!-- stores the hidden frames. -->
......@@ -81,8 +121,8 @@
Visibility="Visible"/>
</Grid>
</SplitView.Content>
</SplitView>
</SplitView.Content>
</SplitView>
</SplitView>
</SplitView.Content>
</SplitView>
</Grid>
</Page>
......@@ -51,6 +51,8 @@ MainPage::MainPage()
{
InitializeComponent();
Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &MainPage::OnResize);
_welcomeFrame_->Navigate(TypeName(RingClientUWP::Views::WelcomePage::typeid));
_smartPanel_->Navigate(TypeName(RingClientUWP::Views::SmartPanel::typeid));
_consolePanel_->Navigate(TypeName(RingClientUWP::Views::RingConsolePanel::typeid));
......@@ -64,6 +66,10 @@ MainPage::MainPage()
ContactsViewModel::instance->noContactSelected += ref new NoContactSelected([&]() {
showFrame(_welcomeFrame_);
});
DisplayInformation^ displayInformation = DisplayInformation::GetForCurrentView();
dpiChangedtoken = (displayInformation->DpiChanged += ref new TypedEventHandler<DisplayInformation^,
Platform::Object^>(this, &MainPage::DisplayProperties_DpiChanged));
}
void
......@@ -109,4 +115,91 @@ void
RingClientUWP::MainPage::OnNavigatedTo(NavigationEventArgs ^ e)
{
RingD::instance->startDaemon();
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;
}
OnResize(nullptr, nullptr);
}
else if (!load) {
isLoading = false;
_fadeOutStoryboard_->Begin();
}
}
void
RingClientUWP::MainPage::PositionImage()
{
bounds = ApplicationView::GetForCurrentView()->VisibleBounds;
auto img = ref new Image();
auto bitmapImage = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
Windows::Foundation::Uri^ uri;
if (bounds.Width < 1200)
uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/TESTS/logo-ring.scale-200.png");
else
uri = ref new Windows::Foundation::Uri("ms-appx:///Assets/TESTS/logo-ring.scale-150.png");
bitmapImage->UriSource = uri;
img->Source = bitmapImage;
_loadingImage_->Source = img->Source;
_loadingImage_->SetValue(Canvas::LeftProperty, bounds.Width * 0.5 - _loadingImage_->Width * 0.5);
_loadingImage_->SetValue(Canvas::TopProperty, bounds.Height * 0.5 - _loadingImage_->Height * 0.5);
}
void
RingClientUWP::MainPage::PositionRing()
{
double left;
double top;
if (bounds.Width < 1200) {
_splashProgressRing_->Width = 118;
_splashProgressRing_->Height = 118;
left = bounds.Width * 0.5 - _loadingImage_->Width * 0.5 - 145;
top = bounds.Height * 0.5 - _loadingImage_->Height * 0.5 - 60;
}
else {
_splashProgressRing_->Width = 162;
_splashProgressRing_->Height = 162;
left = bounds.Width * 0.5 - _loadingImage_->Width * 0.5 - 195;
top = bounds.Height * 0.5 - _loadingImage_->Height * 0.5 - 84;
}
_splashProgressRing_->SetValue(Canvas::LeftProperty, left + _loadingImage_->Width * 0.5);
_splashProgressRing_->SetValue(Canvas::TopProperty, top + _loadingImage_->Height * 0.5);
}
void
RingClientUWP::MainPage::OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
PositionImage();
PositionRing();
}
void
RingClientUWP::MainPage::DisplayProperties_DpiChanged(DisplayInformation^ sender, Platform::Object^ args)
{
OnResize(nullptr, nullptr);
}
void
RingClientUWP::MainPage::hideLoadingOverlay()
{
_loadingOverlay_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
\ No newline at end of file
......@@ -20,6 +20,7 @@
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::Foundation;
namespace RingClientUWP
{
......@@ -29,11 +30,25 @@ public ref class MainPage sealed
{
public:
MainPage();
void showLoadingOverlay(bool load, bool modal);
void hideLoadingOverlay();
property bool isLoading;
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
virtual void OnKeyDown(KeyRoutedEventArgs^ e) override;
void PositionImage();
void PositionRing();
void OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
private:
// Multi-monitor, DPI, scale factor change, and window resize detection
void DisplayProperties_DpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
Windows::Foundation::EventRegistrationToken dpiChangedtoken;
Rect bounds;
void _toggleSmartBoxButton__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void showFrame(Windows::UI::Xaml::Controls::Frame^ frame);
};
......
......@@ -207,10 +207,11 @@ RingClientUWP::RingD::startDaemon()
int detailsCode, const std::string& detailsStr)
{
MSG_("<RegistrationStateChanged>: ID = " + account_id + "state = " + state);
if (state == DRing::Account::States::UNREGISTERED) {
if (state == DRing::Account::States::REGISTERED) {
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Normal,
ref new DispatchedHandler([=]() {
reloadAccountList();
auto frame = dynamic_cast<Frame^>(Window::Current->Content);
dynamic_cast<RingClientUWP::MainPage^>(frame->Content)->showLoadingOverlay(false, false);
}));
}
}),
......
......@@ -130,7 +130,6 @@ void RingClientUWP::Views::SmartPanel::_shareMenuButton__Unchecked(Platform::Obj
_shareMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
}
void RingClientUWP::Views::SmartPanel::_addAccountBtn__Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
_accountsMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
......@@ -143,6 +142,11 @@ void RingClientUWP::Views::SmartPanel::_createAccountYes__Click(Platform::Object
{
case 0:
{
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::High,
ref new DispatchedHandler([=]() {
auto frame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
dynamic_cast<RingClientUWP::MainPage^>(frame->Content)->showLoadingOverlay(true, true);
}));
RingD::instance->createRINGAccount(_aliasTextBox_->Text);
_accountCreationMenuGrid_->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
_accountsMenuButton__Checked(nullptr, nullptr);
......@@ -159,6 +163,7 @@ void RingClientUWP::Views::SmartPanel::_createAccountYes__Click(Platform::Object
default:
break;
}
_aliasTextBox_->Text = "";
}
......
......@@ -59,22 +59,25 @@ UserPreferences::load()
.then([this,preferencesFile](bool contacts_file_exists)
{
if (contacts_file_exists) {
RingDebug::instance->print("opened preferences file");
try {
create_task(ApplicationData::Current->LocalFolder->GetFileAsync(preferencesFile))
.then([this](StorageFile^ file)
{
create_task(FileIO::ReadTextAsync(file))
.then([this](String^ fileContents){
RingDebug::instance->print("reading preferences file");
if (fileContents != nullptr) {
Destringify(fileContents);
// select account index after loading preferences
selectIndex(PREF_ACCOUNT_INDEX);
if (PREF_PROFILE_PHOTO)
loadProfileImage();
}
});
try {
create_task(FileIO::ReadTextAsync(file))
.then([this](String^ fileContents){
if (fileContents != nullptr) {
Destringify(fileContents);
// select account index after loading preferences
selectIndex(PREF_ACCOUNT_INDEX);
if (PREF_PROFILE_PHOTO)
loadProfileImage();
}
});
}
catch (Exception^ e) {
RingDebug::instance->print("Exception while reading preferences file");
}
});
}
catch (Exception^ e) {
......
......@@ -23,15 +23,18 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid x:Name="_welcomePage_"
>
<!--<TextBlock x:Uid="_welcomeMsg"
x:Name="_welcomeMsg_"
Style="{StaticResource TextStyle1}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextWrapping="Wrap" />-->
<Image Source="Assets\TESTS\logo-ring.scale-125.png"/>
</StackPanel>
<Image x:Name="_welcomeImage_"
Source="Assets\TESTS\logo-ring.square-100.png"
Width="310"
Height="310"/>
</Grid>
</Page>
......@@ -25,4 +25,23 @@ using namespace RingClientUWP::Views;
WelcomePage::WelcomePage()
{
InitializeComponent();
};
\ No newline at end of file
Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &WelcomePage::OnResize);
OnResize(nullptr, nullptr);
};
void
WelcomePage::PositionImage()
{
Rect imageBounds;
imageBounds.Width = _welcomePage_->ActualWidth;
imageBounds.Height = _welcomePage_->ActualWidth;
_welcomeImage_->SetValue(Canvas::LeftProperty, imageBounds.Width * 0.5 - _welcomeImage_->Width * 0.5);
_welcomeImage_->SetValue(Canvas::TopProperty, imageBounds.Height * 0.5 - _welcomeImage_->Height * 0.5);
}
void
WelcomePage::OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
PositionImage();
}
\ No newline at end of file
......@@ -26,6 +26,9 @@ public ref class WelcomePage sealed
{
public:
WelcomePage();
protected:
void PositionImage();
void OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
};
}
}
\ No newline at end of file
......@@ -18,8 +18,8 @@
**************************************************************************/
/* standard system include files. */
#include <ppltasks.h>
#include <iomanip>
#include <ppltasks.h>
#include <queue>
/* required by generated headers. */
......@@ -31,9 +31,10 @@
#include "Contact.h"
#include "ContactsViewModel.h"
#include "Conversation.h"
#include "MainPage.xaml.h"
/* ensure to be accessed from anywhere */
#include "RingD.h"
#include "RingDebug.h"
#include "Utils.h"
#include "UserPreferences.h"
#include "UserPreferences.h"
\ No newline at end of file
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