diff --git a/src/OpenSpartan.Workshop/Core/UserContextManager.cs b/src/OpenSpartan.Workshop/Core/UserContextManager.cs index 37fdae3..5da83a9 100644 --- a/src/OpenSpartan.Workshop/Core/UserContextManager.cs +++ b/src/OpenSpartan.Workshop/Core/UserContextManager.cs @@ -213,45 +213,53 @@ internal static bool InitializeHaloClient(AuthenticationResult authResult) extendedTicket = await manager.RequestXstsToken(ticket.Token, false); }).GetAwaiter().GetResult(); - Task.Run(async () => - { - haloToken = await haloAuthClient.GetSpartanToken(haloTicket.Token, 4); - }).GetAwaiter().GetResult(); - - if (extendedTicket != null) + if (haloTicket != null) { - XboxUserContext = extendedTicket; - - HaloClient = new(haloToken.Token, extendedTicket.DisplayClaims.Xui[0].XUID, userAgent: $"{Configuration.PackageName}/{Configuration.Version}-{Configuration.BuildId}"); - Task.Run(async () => { - PlayerClearance? clearance = null; + haloToken = await haloAuthClient.GetSpartanToken(haloTicket.Token, 4); + }).GetAwaiter().GetResult(); - if ((bool)SettingsViewModel.Instance.Settings.UseObanClearance) - { - clearance = (await SafeAPICall(async () => { return await HaloClient.SettingsActiveFlight(SettingsViewModel.Instance.Settings.Sandbox, SettingsViewModel.Instance.Settings.Build, SettingsViewModel.Instance.Settings.Release); })).Result; - } - else - { - clearance = (await SafeAPICall(async () => { return await HaloClient.SettingsActiveClearance(SettingsViewModel.Instance.Settings.Release); })).Result; - } + if (extendedTicket != null) + { + XboxUserContext = extendedTicket; - if (clearance != null && !string.IsNullOrWhiteSpace(clearance.FlightConfigurationId)) - { - HaloClient.ClearanceToken = clearance.FlightConfigurationId; - LogEngine.Log($"Your clearance is {clearance.FlightConfigurationId} and it's set in the client."); - } - else + HaloClient = new(haloToken.Token, extendedTicket.DisplayClaims.Xui[0].XUID, userAgent: $"{Configuration.PackageName}/{Configuration.Version}-{Configuration.BuildId}"); + + Task.Run(async () => { - LogEngine.Log("Could not obtain the clearance.", LogSeverity.Error); - } - }).GetAwaiter().GetResult(); + PlayerClearance? clearance = null; - return true; + if ((bool)SettingsViewModel.Instance.Settings.UseObanClearance) + { + clearance = (await SafeAPICall(async () => { return await HaloClient.SettingsActiveFlight(SettingsViewModel.Instance.Settings.Sandbox, SettingsViewModel.Instance.Settings.Build, SettingsViewModel.Instance.Settings.Release); })).Result; + } + else + { + clearance = (await SafeAPICall(async () => { return await HaloClient.SettingsActiveClearance(SettingsViewModel.Instance.Settings.Release); })).Result; + } + + if (clearance != null && !string.IsNullOrWhiteSpace(clearance.FlightConfigurationId)) + { + HaloClient.ClearanceToken = clearance.FlightConfigurationId; + LogEngine.Log($"Your clearance is {clearance.FlightConfigurationId} and it's set in the client."); + } + else + { + LogEngine.Log("Could not obtain the clearance.", LogSeverity.Error); + } + }).GetAwaiter().GetResult(); + + return true; + } + else + { + return false; + } } else { + LogEngine.Log("Halo ticket is null. Cannot authenticate.", LogSeverity.Error); return false; } } @@ -1963,105 +1971,127 @@ internal static async Task InitializeAllDataOnLaunch() { var instantiationResult = InitializeHaloClient(authResult); - await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => - { - SplashScreenViewModel.Instance.IsBlocking = false; - }); - if (instantiationResult) { - if (string.IsNullOrWhiteSpace(HaloClient.ClearanceToken)) - { - LogEngine.Log($"The clearance is empty, so many API calls that depend on it may fail."); - } - - HomeViewModel.Instance.Gamertag = XboxUserContext.DisplayClaims.Xui[0].Gamertag; - HomeViewModel.Instance.Xuid = XboxUserContext.DisplayClaims.Xui[0].XUID; - - var databaseBootstrapResult = DataHandler.BootstrapDatabase(); - var journalingMode = DataHandler.SetWALJournalingMode(); - - if (journalingMode.Equals("wal", StringComparison.Ordinal)) - { - LogEngine.Log("Successfully set WAL journaling mode."); - } - else - { - LogEngine.Log("Could not set WAL journaling mode.", LogSeverity.Warning); - } - await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => { - // Reset all collections to make sure that left-over data is not displayed. - BattlePassViewModel.Instance.BattlePasses = BattlePassViewModel.Instance.BattlePasses ?? []; - MatchesViewModel.Instance.MatchList = MatchesViewModel.Instance.MatchList ?? []; - MedalsViewModel.Instance.Medals = MedalsViewModel.Instance.Medals ?? []; + SplashScreenViewModel.Instance.IsBlocking = false; }); - // We want to populate the medal metadata before we do anything else. - MedalMetadata = await PrepopulateMedalMetadata(); + if (instantiationResult) + { + if (string.IsNullOrWhiteSpace(HaloClient.ClearanceToken)) + { + LogEngine.Log($"The clearance is empty, so many API calls that depend on it may fail."); + } - // Let's get career data first to make sure that it's quickly populated. - _ = await PopulateCareerData(); + HomeViewModel.Instance.Gamertag = XboxUserContext.DisplayClaims.Xui[0].Gamertag; + HomeViewModel.Instance.Xuid = XboxUserContext.DisplayClaims.Xui[0].XUID; - // Service Record data should be pulled early to make sure that we - // get the latest medals quickly before everything else is populated. - _ = await PopulateServiceRecordData(); + var databaseBootstrapResult = DataHandler.BootstrapDatabase(); + var journalingMode = DataHandler.SetWALJournalingMode(); - Parallel.Invoke( - async () => await PopulateMedalData(), - async () => await PopulateExchangeData(), - async () => await PopulateCsrImages(), - async () => + if (journalingMode.Equals("wal", StringComparison.Ordinal)) { - try - { - await PopulateSeasonCalendar(); - } - catch (Exception ex) - { - LogEngine.Log($"Could not populate the calendar. {ex.Message}", LogSeverity.Error); - } - }, - async () => await PopulateUserInventory(), - async () => await PopulateCustomizationData(), - async () => await PopulateDecorationData(), - async () => + LogEngine.Log("Successfully set WAL journaling mode."); + } + else { - var matchRecordsOutcome = await PopulateMatchRecordsData(); + LogEngine.Log("Could not set WAL journaling mode.", LogSeverity.Warning); + } - if (matchRecordsOutcome) + await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + { + // Reset all collections to make sure that left-over data is not displayed. + BattlePassViewModel.Instance.BattlePasses = BattlePassViewModel.Instance.BattlePasses ?? []; + MatchesViewModel.Instance.MatchList = MatchesViewModel.Instance.MatchList ?? []; + MedalsViewModel.Instance.Medals = MedalsViewModel.Instance.Medals ?? []; + }); + + // We want to populate the medal metadata before we do anything else. + MedalMetadata = await PrepopulateMedalMetadata(); + + // Let's get career data first to make sure that it's quickly populated. + _ = await PopulateCareerData(); + + // Service Record data should be pulled early to make sure that we + // get the latest medals quickly before everything else is populated. + _ = await PopulateServiceRecordData(); + + Parallel.Invoke( + async () => await PopulateMedalData(), + async () => await PopulateExchangeData(), + async () => await PopulateCsrImages(), + async () => { - await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + try { - MatchesViewModel.Instance.MatchLoadingState = MetadataLoadingState.Completed; - MatchesViewModel.Instance.MatchLoadingParameter = string.Empty; - }); - } - }, - async () => - { - try + await PopulateSeasonCalendar(); + } + catch (Exception ex) + { + LogEngine.Log($"Could not populate the calendar. {ex.Message}", LogSeverity.Error); + } + }, + async () => await PopulateUserInventory(), + async () => await PopulateCustomizationData(), + async () => await PopulateDecorationData(), + async () => { - await PopulateBattlePassData(BattlePassLoadingCancellationTracker.Token); + var matchRecordsOutcome = await PopulateMatchRecordsData(); - await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + if (matchRecordsOutcome) { - BattlePassViewModel.Instance.BattlePassLoadingState = MetadataLoadingState.Completed; - }); - } - catch + await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + { + MatchesViewModel.Instance.MatchLoadingState = MetadataLoadingState.Completed; + MatchesViewModel.Instance.MatchLoadingParameter = string.Empty; + }); + } + }, + async () => { - BattlePassLoadingCancellationTracker = new CancellationTokenSource(); - } - }); + try + { + await PopulateBattlePassData(BattlePassLoadingCancellationTracker.Token); - return true; + await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + { + BattlePassViewModel.Instance.BattlePassLoadingState = MetadataLoadingState.Completed; + }); + } + catch + { + BattlePassLoadingCancellationTracker = new CancellationTokenSource(); + } + }); + + return true; + } + + return false; + } + else + { + await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + { + SplashScreenViewModel.Instance.IsErrorMessageDisplayed = true; + }); + + LogEngine.Log("Could not authenticate with Halo services.", LogSeverity.Error); + return false; } + } + else + { + await DispatcherWindow.DispatcherQueue.EnqueueAsync(() => + { + SplashScreenViewModel.Instance.IsErrorMessageDisplayed = true; + }); + LogEngine.Log("Could not authenticate with Halo services.", LogSeverity.Error); return false; } - return false; } } } diff --git a/src/OpenSpartan.Workshop/MainWindow.xaml b/src/OpenSpartan.Workshop/MainWindow.xaml index c48a15a..7941a56 100644 --- a/src/OpenSpartan.Workshop/MainWindow.xaml +++ b/src/OpenSpartan.Workshop/MainWindow.xaml @@ -84,7 +84,15 @@ - + + + + + + + + + diff --git a/src/OpenSpartan.Workshop/ViewModels/SplashScreenViewModel.cs b/src/OpenSpartan.Workshop/ViewModels/SplashScreenViewModel.cs index c098067..e682e2e 100644 --- a/src/OpenSpartan.Workshop/ViewModels/SplashScreenViewModel.cs +++ b/src/OpenSpartan.Workshop/ViewModels/SplashScreenViewModel.cs @@ -10,6 +10,20 @@ internal sealed class SplashScreenViewModel : Observable private SplashScreenViewModel() { IsBlocking = true; + IsErrorMessageDisplayed = false; + } + + public bool IsErrorMessageDisplayed + { + get => _isErrorMessageDisplayed; + set + { + if (_isErrorMessageDisplayed != value) + { + _isErrorMessageDisplayed = value; + NotifyPropertyChanged(); + } + } } public bool IsBlocking @@ -25,6 +39,7 @@ public bool IsBlocking } } + private bool _isErrorMessageDisplayed; private bool _isBlocking; public void NotifyPropertyChanged([CallerMemberName] string? propertyName = null) diff --git a/src/OpenSpartan.Workshop/Views/HomeView.xaml b/src/OpenSpartan.Workshop/Views/HomeView.xaml index f3c753a..7070765 100644 --- a/src/OpenSpartan.Workshop/Views/HomeView.xaml +++ b/src/OpenSpartan.Workshop/Views/HomeView.xaml @@ -55,66 +55,66 @@ - - - - - - + + + + + + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + - - - - - - + + + + + + @@ -130,7 +130,7 @@ - + @@ -152,7 +152,7 @@ - + @@ -675,98 +675,5 @@ - - - - - -