diff --git a/src/DynamoCore/Core/IDSDKManager.cs b/src/DynamoCore/Core/IDSDKManager.cs index 5b5d7cc7fbf..b3411d11d78 100644 --- a/src/DynamoCore/Core/IDSDKManager.cs +++ b/src/DynamoCore/Core/IDSDKManager.cs @@ -10,7 +10,7 @@ namespace Dynamo.Core /// /// The class to provide auth APIs for IDSDK related methods. /// - public class IDSDKManager : IOAuth2AuthProvider, IOAuth2AccessTokenProvider + public class IDSDKManager : IOAuth2AuthProvider, IOAuth2AccessTokenProvider, IDisposable { /// /// Used by the auth provider to request authentication. @@ -228,8 +228,10 @@ private bool Initialize() } bool ret = GetClientIDAndServer(out idsdk_server server, out string client_id); - if (ret) + if (ret) { + Client.LogoutCompleteEvent += AuthCompleteEventHandler; + Client.LoginCompleteEvent += AuthCompleteEventHandler; ret = SetProductConfigs("Dynamo", server, client_id); Client.SetServer(server); return ret; @@ -253,6 +255,11 @@ private bool Deinitialize() } return false; } + public void Dispose() + { + Client.LoginCompleteEvent -= AuthCompleteEventHandler; + Client.LogoutCompleteEvent -= AuthCompleteEventHandler; + } private bool GetClientIDAndServer(out idsdk_server server, out string client_id) { server = idsdk_server.IDSDK_PRODUCTION_SERVER; @@ -273,6 +280,12 @@ private bool GetClientIDAndServer(out idsdk_server server, out string client_id) } return !string.IsNullOrEmpty(client_id); } + + // Event handler for LogoutCompleteEvent and LoginCompleteEvent that is thrown whenever the user's auth state changes. + private void AuthCompleteEventHandler(object sender, Client.TypedEventArgs e) + { + OnLoginStateChanged(LoginState); + } #endregion } } diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 1be01a36080..996e074533b 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -1456,6 +1456,11 @@ public void Dispose() { SearchModel.ItemProduced -= SearchModel_ItemProduced; } + //handle the disposal of IDSDK manager instance for sandbox + if (AuthenticationManager?.AuthProvider is IDSDKManager idsdkProvider) + { + idsdkProvider?.Dispose(); + } } private void InitializeCustomNodeManager() diff --git a/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs b/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs index 16b971cfb12..043d9f46b03 100644 --- a/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs +++ b/src/DynamoCoreWpf/Controls/ShortcutToolbar.xaml.cs @@ -11,13 +11,14 @@ using System.Linq; using System.Windows; using System.Collections.Generic; +using System; namespace Dynamo.UI.Controls { /// /// An object which provides the data for the shortcut toolbar. /// - public partial class ShortcutToolbar : UserControl + public partial class ShortcutToolbar : UserControl, IDisposable { private readonly ObservableCollection shortcutBarItems; private readonly ObservableCollection shortcutBarRightSideItems; @@ -57,7 +58,7 @@ public ShortcutToolbar(DynamoViewModel dynamoViewModel) authManager = dynamoViewModel.Model.AuthenticationManager; if (authManager.IsLoggedInInitial()) { - authManager.LoginStateChanged += SignOutHandler; + authManager.LoginStateChanged += AuthChangeHandler; } else { logoutOption.Visibility = Visibility.Collapsed; @@ -73,14 +74,28 @@ private void ShortcutToolbar_Loaded(object sender, RoutedEventArgs e) DynamoViewModel.OnRequestShorcutToolbarLoaded(RightMenu.ActualWidth); } - private void SignOutHandler(LoginState status) + public void Dispose() + { + if(authManager != null) + { + authManager.LoginStateChanged -= AuthChangeHandler; + } + this.Loaded -= ShortcutToolbar_Loaded; + } + + private void AuthChangeHandler(LoginState status) { if (status == LoginState.LoggedOut) { LoginButton.ToolTip = Wpf.Properties.Resources.SignInButtonContentToolTip; txtSignIn.Text = Wpf.Properties.Resources.SignInButtonText; logoutOption.Visibility = Visibility.Collapsed; - authManager.LoginStateChanged -= SignOutHandler; + } + else if (status == LoginState.LoggedIn) + { + txtSignIn.Text = authManager.Username; + logoutOption.Visibility = Visibility.Visible; + LoginButton.ToolTip = null; } } @@ -115,7 +130,6 @@ private void LoginButton_OnClick(object sender, RoutedEventArgs e) tb.Text = authManager.Username; logoutOption.Visibility = Visibility.Visible; LoginButton.ToolTip = null; - authManager.LoginStateChanged += SignOutHandler; } } } diff --git a/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs b/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs index 50f60a268d2..dd792f33de7 100644 --- a/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs +++ b/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs @@ -2963,6 +2963,7 @@ public void Dispose() // Removing the tab items list handler dynamoViewModel.SideBarTabItems.CollectionChanged -= this.OnCollectionChanged; + shortcutBar?.Dispose(); if (fileTrustWarningPopup != null) { diff --git a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs index db0c28c3298..2e74db5b428 100644 --- a/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs +++ b/src/DynamoCoreWpf/Views/SplashScreen/SplashScreen.xaml.cs @@ -14,6 +14,7 @@ using Dynamo.Utilities; using Dynamo.ViewModels; using DynamoUtilities; +using Greg.AuthProviders; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.Wpf; @@ -129,9 +130,15 @@ public void OnRequestStaticSplashScreen() } /// - /// Constructor + /// Stores the value that indicates if the SignIn Button will be enabled(default) or not /// - public SplashScreen() + bool enableSignInButton; + + /// + /// Splash Screen Constructor. + /// Indicates if the SignIn Button will be enabled(default) or not. + /// + public SplashScreen(bool enableSignInButton = true) { InitializeComponent(); @@ -149,6 +156,7 @@ public SplashScreen() RequestImportSettings = ImportSettings; RequestSignIn = SignIn; RequestSignOut = SignOut; + this.enableSignInButton = enableSignInButton; } private void DynamoModel_LanguageDetected() @@ -230,12 +238,16 @@ private void LaunchDynamo(bool isCheckboxChecked) { viewModel.PreferenceSettings.EnableStaticSplashScreen = !isCheckboxChecked; } - StaticSplashScreenReady -= OnStaticScreenReady; Close(); dynamoView?.Show(); dynamoView?.Activate(); } + private void OnLoginStateChanged(LoginState state) + { + HandleSignInStatusChange(authManager.IsLoggedIn()); + } + /// /// Once main window is initialized, Dynamic Splash screen should finish loading /// @@ -250,6 +262,7 @@ private void OnStaticScreenReady() // If user is launching Dynamo for the first time or chose to always show splash screen, display it. Otherwise, display Dynamo view directly. if (viewModel.PreferenceSettings.IsFirstRun || viewModel.PreferenceSettings.EnableStaticSplashScreen) { + authManager.LoginStateChanged += OnLoginStateChanged; SetSignInStatus(authManager.IsLoggedInInitial()); SetLoadingDone(); } @@ -346,6 +359,7 @@ internal async void SetLoadingDone() { await webView.CoreWebView2.ExecuteScriptAsync($"window.setLoadingDone()"); await webView.CoreWebView2.ExecuteScriptAsync($"window.setTotalLoadingTime(\"{Wpf.Properties.Resources.SplashScreenTotalLoadingTimeLabel} {totalLoadingTime}ms\")"); + SetSignInEnable(enableSignInButton); } } @@ -393,6 +407,28 @@ await webView.CoreWebView2.ExecuteScriptAsync("window.setSignInStatus({" + } } + /// + /// Handle the login status changes on splash screen. + /// + internal async void HandleSignInStatusChange(bool status) + { + if (webView?.CoreWebView2 != null) + { + await webView.CoreWebView2.ExecuteScriptAsync(@$"window.handleSignInStateChange({{""status"": ""{status}""}})"); + } + } + + /// + /// Enable or disable the SignIn button on splash screen. + /// + /// + internal async void SetSignInEnable(bool enabled) + { + if (webView?.CoreWebView2 != null) + { + await webView.CoreWebView2.ExecuteScriptAsync(@$"window.setEnableSignInButton({{""enable"": ""{enabled}""}})"); + } + } /// /// Setup the values for all labels on splash screen using resources /// @@ -509,6 +545,8 @@ protected override void OnClosed(EventArgs e) DynamoModel.RequestUpdateLoadBarStatus -= DynamoModel_RequestUpdateLoadBarStatus; DynamoModel.LanguageDetected -= DynamoModel_LanguageDetected; + StaticSplashScreenReady -= OnStaticScreenReady; + authManager.LoginStateChanged -= OnLoginStateChanged; webView.Dispose(); webView = null;