diff --git a/Float.TinCan.ActivityLibrary/ActivityLaunchCoordinator.cs b/Float.TinCan.ActivityLibrary/ActivityLaunchCoordinator.cs index 133cdeb..77cfb7b 100644 --- a/Float.TinCan.ActivityLibrary/ActivityLaunchCoordinator.cs +++ b/Float.TinCan.ActivityLibrary/ActivityLaunchCoordinator.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Float.Core.UI; using Float.Core.UX; using Float.FileDownloader; @@ -29,6 +30,7 @@ public abstract class ActivityLaunchCoordinator : Coordinator string startLocation; DownloadStatus downloadStatus; + bool isCreatingRunner; /// /// Initializes a new instance of the class. @@ -76,6 +78,14 @@ protected ActivityLaunchCoordinator(IActivity activity, IRemoteFileProvider remo /// The managed html activity runner page. protected BaseContentPage ManagedHtmlActivityRunnerPage { get; set; } + /// + /// Gets a value indicating whether this is creating a runner, which may inform the implementing instance it would not want to allow finishing of the coordinator. + /// + /// + /// A value indicating whether this is creating a runner, which may inform the implementing instance it would not want to allow finishing of the coordinator. + /// + protected bool IsCreatingRunner => isCreatingRunner; + /// public override void Start() { @@ -101,7 +111,7 @@ public override void Start() } else { - Device.BeginInvokeOnMainThread(() => + Device.BeginInvokeOnMainThread(async () => { try { @@ -118,8 +128,7 @@ public override void Start() downloadStatus.DownloadsCompleted += HandleDownloadCompleted; downloadStatus.DownloadsCancelled += HandleDownloadCancelled; - - NavigationContext.PresentPage(CreateDownloadStatusPage(downloadStatus)); + await ShowDownloadStatus(CreateDownloadStatusPage(downloadStatus)); }); } } @@ -129,7 +138,31 @@ public override void Start() /// /// The download status page. /// Download status. - protected abstract BaseContentPage CreateDownloadStatusPage(DownloadStatus downloadStatus); + protected abstract ContentPage CreateDownloadStatusPage(DownloadStatus downloadStatus); + + /// + /// Shows the download status page. + /// + /// The download status page. + /// A representing the asynchronous operation. + protected virtual async Task ShowDownloadStatus(ContentPage downloadStatusPage) + { + if (downloadStatusPage is null) + { + throw new ArgumentNullException(nameof(downloadStatusPage)); + } + + await NavigationContext.PresentPageAsync(downloadStatusPage); + } + + /// + /// Dismisses the download status page. + /// + /// A representing the asynchronous operation. + protected virtual async Task DismissDownloadStatus() + { + await NavigationContext.PopPageAsync(); + } /// /// Creates the activity complete page. @@ -153,6 +186,11 @@ public override void Start() /// protected override void Finish(EventArgs args) { + if (isCreatingRunner) + { + return; + } + base.Finish(args); try { @@ -205,10 +243,10 @@ protected virtual void OnActivityFinished(object sender, EventArgs args) /// protected void ShowCompletionScreen() { - Device.BeginInvokeOnMainThread(() => + Device.BeginInvokeOnMainThread(async () => { var completionPage = CreateActivityCompletePage(AvailablePostAssessments != null && AvailablePostAssessments.Any()); - NavigationContext.PresentPage(completionPage); + await NavigationContext.PresentPageAsync(completionPage); }); } @@ -318,19 +356,21 @@ protected virtual void HandleAssessmentFailed(object sender, EventArgs args) /// /// The sending object. /// Arguments related to the event. - protected virtual void HandleDownloadCompleted(object sender, EventArgs args) + protected virtual async void HandleDownloadCompleted(object sender, EventArgs args) { if (downloadStatus != null && downloadStatus.State != DownloadStatus.DownloadState.Error) { downloadStatus.DownloadsCompleted -= HandleDownloadCompleted; downloadStatus.DownloadsCancelled -= HandleDownloadCancelled; - NavigationContext.DismissPage(); startLocation = Activity.MetaData.StartLocation; + isCreatingRunner = true; + await DismissDownloadStatus(); CreateRunnerAndHandleErrors(); downloadStatus = null; + isCreatingRunner = false; } else { @@ -343,7 +383,7 @@ protected virtual void HandleDownloadCompleted(object sender, EventArgs args) /// /// The sending object. /// Arguments related to the event. - protected virtual void HandleDownloadCancelled(object sender, EventArgs args) + protected virtual async void HandleDownloadCancelled(object sender, EventArgs args) { if (downloadStatus != null) { @@ -351,7 +391,8 @@ protected virtual void HandleDownloadCancelled(object sender, EventArgs args) downloadStatus.DownloadsCancelled -= HandleDownloadCancelled; } - NavigationContext.DismissPage(); + await DismissDownloadStatus(); + downloadStatus = null; } @@ -373,11 +414,11 @@ protected virtual void HandleDownloadError(object sender, EventArgs args) void CreateRunnerAndHandleErrors() { - Device.BeginInvokeOnMainThread(() => + Device.BeginInvokeOnMainThread(async () => { try { - CreateRunner(); + await CreateRunner(); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) @@ -392,7 +433,7 @@ void CreateRunnerAndHandleErrors() /// /// Creates the runner. Note that this method expects to be called on the main thread. /// - void CreateRunner() + async Task CreateRunner() { // because this method is always invoked on the main thread, it's possible this coordinator was finished on a different thread first // this can cause all sorts of problems because we create a runner and never dispose it @@ -449,7 +490,7 @@ void CreateRunner() throw new InvalidOperationException($"No navigation context for activity {Activity.Name}"); } - NavigationContext.PushPage(ManagedHtmlActivityRunnerPage); + await NavigationContext.PushPageAsync(ManagedHtmlActivityRunnerPage); } } } diff --git a/Float.TinCan.ActivityLibrary/Float.TinCan.ActivityLibrary.csproj b/Float.TinCan.ActivityLibrary/Float.TinCan.ActivityLibrary.csproj index c946feb..124f8f4 100644 --- a/Float.TinCan.ActivityLibrary/Float.TinCan.ActivityLibrary.csproj +++ b/Float.TinCan.ActivityLibrary/Float.TinCan.ActivityLibrary.csproj @@ -32,8 +32,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all