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
diff --git a/MainPage.xaml b/MainPage.xaml
index 31d3e27..7dc2143 100644
--- a/MainPage.xaml
+++ b/MainPage.xaml
@@ -1,6 +1,7 @@
<!-- **********************************************************************
* 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>
diff --git a/MainPage.xaml.cpp b/MainPage.xaml.cpp
index d6b4bb9..5e30336 100644
--- a/MainPage.xaml.cpp
+++ b/MainPage.xaml.cpp
@@ -51,6 +51,8 @@
{
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 @@
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 @@
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
diff --git a/MainPage.xaml.h b/MainPage.xaml.h
index 7b9691b..aa76667 100644
--- a/MainPage.xaml.h
+++ b/MainPage.xaml.h
@@ -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:
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);
};
diff --git a/RingD.cpp b/RingD.cpp
index 3abac15..b52c2e2 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -207,10 +207,11 @@
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);
}));
}
}),
diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp
index 2366bec..db4bf79 100644
--- a/SmartPanel.xaml.cpp
+++ b/SmartPanel.xaml.cpp
@@ -130,7 +130,6 @@
_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 @@
{
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 @@
default:
break;
}
+ _aliasTextBox_->Text = "";
}
diff --git a/UserPreferences.cpp b/UserPreferences.cpp
index 026f749..2307c78 100644
--- a/UserPreferences.cpp
+++ b/UserPreferences.cpp
@@ -59,22 +59,25 @@
.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) {
diff --git a/WelcomePage.xaml b/WelcomePage.xaml
index f9aa112..d4f01f6 100644
--- a/WelcomePage.xaml
+++ b/WelcomePage.xaml
@@ -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>
diff --git a/WelcomePage.xaml.cpp b/WelcomePage.xaml.cpp
index 7112811..1a22547 100644
--- a/WelcomePage.xaml.cpp
+++ b/WelcomePage.xaml.cpp
@@ -25,4 +25,23 @@
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
diff --git a/WelcomePage.xaml.h b/WelcomePage.xaml.h
index 29cb127..1f37c15 100644
--- a/WelcomePage.xaml.h
+++ b/WelcomePage.xaml.h
@@ -26,6 +26,9 @@
{
public:
WelcomePage();
+protected:
+ void PositionImage();
+ void OnResize(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
};
}
}
\ No newline at end of file
diff --git a/pch.h b/pch.h
index daba861..3860e31 100644
--- a/pch.h
+++ b/pch.h
@@ -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