diff options
author | Vitaly Takmazov | 2014-12-23 01:29:17 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2014-12-23 01:29:17 +0300 |
commit | cb08471c057e78d278891f08d03bc4aa41fe4d0d (patch) | |
tree | 3bb69a5de15592993efacfe9b347189b81592ad5 | |
parent | 2fe738b15dd6fb2fd459f260c35fa87c3ae99814 (diff) |
Fast resume
-rw-r--r-- | Juick/App.xaml.cs | 124 | ||||
-rw-r--r-- | Juick/Classes/MyUriMapper.cs | 35 | ||||
-rw-r--r-- | Juick/MainPage.xaml.cs | 31 | ||||
-rw-r--r-- | Juick/ViewModels/AppViewModel.cs | 1 | ||||
-rw-r--r-- | Juick/ViewModels/PageViewModel.cs | 4 |
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));
|