summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2014-12-23 01:29:17 +0300
committerGravatar Vitaly Takmazov2014-12-23 01:29:17 +0300
commitcb08471c057e78d278891f08d03bc4aa41fe4d0d (patch)
tree3bb69a5de15592993efacfe9b347189b81592ad5
parent2fe738b15dd6fb2fd459f260c35fa87c3ae99814 (diff)
Fast resume
-rw-r--r--Juick/App.xaml.cs124
-rw-r--r--Juick/Classes/MyUriMapper.cs35
-rw-r--r--Juick/MainPage.xaml.cs31
-rw-r--r--Juick/ViewModels/AppViewModel.cs1
-rw-r--r--Juick/ViewModels/PageViewModel.cs4
5 files changed, 165 insertions, 30 deletions
diff --git a/Juick/App.xaml.cs b/Juick/App.xaml.cs
index 03e0d10..1e91f38 100644
--- a/Juick/App.xaml.cs
+++ b/Juick/App.xaml.cs
@@ -95,13 +95,17 @@ namespace Juick
null,
"/ApplicationWideTile.png",
null);
+ RootFrame.UriMapper = new MyUriMapper();
}
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
- // Ensure that application state is restored appropriately
+ if (e.IsApplicationInstancePreserved == false)
+ {
+ RootFrame.UriMapper = new MyUriMapper();
+ }
}
// Code to execute when the application is deactivated (sent to background)
@@ -139,9 +143,26 @@ namespace Juick
#region Phone application initialization
+ public enum SessionType
+ {
+ None,
+ Home,
+ DeepLink
+ }
+
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
+ // Set to Home when the app is launched from Primary tile.
+ // Set to DeepLink when the app is launched from Deep Link.
+ private SessionType _sessionType = SessionType.None;
+
+ // Set to true when the page navigation is being reset
+ private bool _wasRelaunched = false;
+
+ // set to true when 5 min passed since the app was relaunched
+ private bool _mustClearPagestack = false;
+
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
@@ -156,10 +177,87 @@ namespace Juick
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
+ RootFrame.Navigated += CheckForResetNavigation;
+
+ RootFrame.Navigating += RootFrame_Navigating;
+
+ RootFrame.UriMapper = new MyUriMapper();
+
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
+ void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
+ {
+ // If the session type is None or New, check the navigation Uri to determine if the
+ // navigation is a deep link or if it points to the app's main page.
+ if (_sessionType == SessionType.None && e.NavigationMode == NavigationMode.New)
+ {
+ // This block will run if the current navigation is part of the app's intial launch
+
+
+ // Keep track of Session Type
+ if (e.Uri.ToString().Contains("DeepLink=true"))
+ {
+ _sessionType = SessionType.DeepLink;
+ }
+ else if (e.Uri.ToString().Contains("/MainPage.xaml"))
+ {
+ _sessionType = SessionType.Home;
+ }
+ }
+
+
+
+ if (e.NavigationMode == NavigationMode.Reset)
+ {
+ // This block will execute if the current navigation is a relaunch.
+ // If so, another navigation will be coming, so this records that a relaunch just happened
+ // so that the next navigation can use this info.
+ _wasRelaunched = true;
+ }
+ else if (e.NavigationMode == NavigationMode.New && _wasRelaunched)
+ {
+ // This block will run if the previous navigation was a relaunch
+ _wasRelaunched = false;
+
+ if (e.Uri.ToString().Contains("ShareContent") || e.Uri.ToString().Contains("mid"))
+ {
+ // This block will run if the launch Uri contains "DeepLink=true" which
+ // was specified when the secondary tile was created in MainPage.xaml.cs
+
+ _sessionType = SessionType.DeepLink;
+ // The app was relaunched via a Deep Link.
+ // The page stack will be cleared.
+ }
+ else if (e.Uri.OriginalString.Contains("/MainPage.xaml"))
+ {
+ // This block will run if the navigation Uri is the main page
+ if (_sessionType == SessionType.DeepLink)
+ {
+ // When the app was previously launched via Deep Link and relaunched via Main Tile, we need to clear the page stack.
+ _sessionType = SessionType.Home;
+ }
+ else
+ {
+ if (!_mustClearPagestack)
+ {
+ //The app was previously launched via Main Tile and relaunched via Main Tile. Cancel the navigation to resume.
+ e.Cancel = true;
+ RootFrame.Navigated -= ClearBackStackAfterReset;
+ }
+ }
+ }
+
+ _mustClearPagestack = false;
+ }
+ else if (e.NavigationMode == NavigationMode.New && !_wasRelaunched && e.Uri.ToString().Contains("/MainPage.xaml"))
+ {
+ // Home button: Any time we do a forward nav to "MainPage" we assume it's from the Home button, so we clear the backstack
+ RootFrame.Navigated += ClearBackStackAfterReset;
+ }
+ }
+
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
@@ -171,6 +269,30 @@ namespace Juick
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
+ private void CheckForResetNavigation(object sender, NavigationEventArgs e)
+ {
+ // If the app has received a 'reset' navigation, then we need to check
+ // on the next navigation to see if the page stack should be reset
+ if (e.NavigationMode == NavigationMode.Reset)
+ RootFrame.Navigated += ClearBackStackAfterReset;
+ }
+
+ private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
+ {
+ // Unregister the event so it doesn't get called again
+ RootFrame.Navigated -= ClearBackStackAfterReset;
+
+ // Only clear the stack for 'new' (forward) and 'refresh' navigations
+ if (e.NavigationMode != NavigationMode.New)
+ return;
+
+ // For UI consistency, clear the entire page stack
+ while (RootFrame.RemoveBackEntry() != null)
+ {
+ ; // do nothing
+ }
+ }
+
#endregion
}
} \ No newline at end of file
diff --git a/Juick/Classes/MyUriMapper.cs b/Juick/Classes/MyUriMapper.cs
new file mode 100644
index 0000000..4f757a5
--- /dev/null
+++ b/Juick/Classes/MyUriMapper.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Navigation;
+
+namespace Juick.Classes
+{
+ public class MyUriMapper : UriMapperBase
+ {
+ public override Uri MapUri(Uri uri)
+ {
+ string tempUri = uri.OriginalString;
+ string mappedUri;
+
+ // Launch from the photo share picker.
+ // Incoming URI example: /MainPage.xaml?Action=ShareContent&FileId=%7BA3D54E2D-7977-4E2B-B92D-3EB126E5D168%7D
+ if ((tempUri.Contains("ShareContent")) && (tempUri.Contains("FileId")))
+ {
+ mappedUri = tempUri.Replace("MainPage", "NewPostView");
+ return new Uri(mappedUri, UriKind.Relative);
+ }
+
+ if (!App.AppContext.Account.IsAuthenticated)
+ {
+ mappedUri = tempUri.Replace("MainPage", "LoginView");
+ return new Uri(mappedUri, UriKind.Relative);
+ }
+
+ // Otherwise perform normal launch.
+ return uri;
+ }
+ }
+}
diff --git a/Juick/MainPage.xaml.cs b/Juick/MainPage.xaml.cs
index edf2d3b..4da88ec 100644
--- a/Juick/MainPage.xaml.cs
+++ b/Juick/MainPage.xaml.cs
@@ -52,35 +52,8 @@ namespace Juick
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
- {
- var loginUriPart = "/LoginView.xaml";
- var newPostUriPart = "/NewPostView.xaml";
- var navigateUri = string.Empty;
- var FileId = string.Empty;
- // Get a dictionary of query string keys and values.
- IDictionary<string, string> queryStrings = NavigationContext.QueryString;
-
- // Ensure that there is at least one key in the query string, and check
- // whether the "FileId" key is present.
-
- navigateUri = App.AppContext.Account.IsAuthenticated ? newPostUriPart : loginUriPart;
- if (queryStrings.ContainsKey("FileId"))
- {
- FileId = queryStrings["FileId"];
- navigateUri = string.Format("{0}?FileId={1}", navigateUri, FileId);
- }
- if (!string.IsNullOrEmpty(FileId) || navigateUri.StartsWith(loginUriPart))
- {
- ((App)Application.Current).NavigateTo(new Uri(navigateUri, UriKind.Relative), true);
- }
- if (queryStrings.ContainsKey("mid"))
- {
- var mid = queryStrings["mid"];
- navigateUri = string.Format("/ThreadView.xaml?mid={0}", mid);
- ((App)Application.Current).NavigateTo(new Uri(navigateUri, UriKind.Relative), true);
- }
- App.AppContext.Client.Authenticator = new HttpBasicAuthenticator(App.AppContext.Account.UserName, App.AppContext.Account.Password);
-
+ {
+ App.AppContext.Client.Authenticator = new HttpBasicAuthenticator(App.AppContext.Account.UserName, App.AppContext.Account.Password);
}
diff --git a/Juick/ViewModels/AppViewModel.cs b/Juick/ViewModels/AppViewModel.cs
index ba33625..4aa9321 100644
--- a/Juick/ViewModels/AppViewModel.cs
+++ b/Juick/ViewModels/AppViewModel.cs
@@ -162,6 +162,7 @@ namespace Juick.ViewModels
public void EnableNotifications()
{
if (!Account.IsAuthenticated) return;
+ if (pushChannel.ChannelUri == null) return;
var channelUri = pushChannel.ChannelUri.ToString();
if (channelUri == Account.NotificationUri)
return;
diff --git a/Juick/ViewModels/PageViewModel.cs b/Juick/ViewModels/PageViewModel.cs
index 9781a9e..c13e6f1 100644
--- a/Juick/ViewModels/PageViewModel.cs
+++ b/Juick/ViewModels/PageViewModel.cs
@@ -73,6 +73,10 @@ namespace Juick.ViewModels
_context.Client.ExecuteAsync<List<Message>>(request, response =>
{
_context.IsDataLoading = false;
+ if (response.ErrorException != null)
+ {
+ return;
+ }
if (response.Data == null)
return;
response.Data.Select(x => new PostItem(x)).ToList().ForEach(i => Items.Add(i));