Krzysztof Krysiński 3 mēneši atpakaļ
vecāks
revīzija
f8ab650a06

+ 17 - 0
src/PixiEditor.Extensions.Runtime/ExtensionLoader.cs

@@ -91,6 +91,23 @@ public class ExtensionLoader
         }
     }
 
+    public void InvokeOnUserReady()
+    {
+        foreach (var extension in LoadedExtensions)
+        {
+            try
+            {
+                extension.UserReady();
+            }
+            catch (Exception ex)
+            {
+#if DEBUG
+                throw;
+#endif
+            }
+        }
+    }
+
     public Extension? LoadExtension(string extension)
     {
         var extZip = ZipFile.OpenRead(extension);

+ 6 - 0
src/PixiEditor.Extensions.Sdk/Bridge/Native.cs

@@ -51,6 +51,12 @@ internal static partial class Native
         ExtensionContext.Active.OnInitialized();
     }
 
+    [ApiExport("user_ready")]
+    internal static void OnUserReady()
+    {
+        ExtensionContext.Active.OnUserReady();
+    }
+
     [ApiExport("raise_element_event")]
     internal static void EventRaised(int internalControlId, string eventName, IntPtr eventData, int dataLength)
     {

+ 6 - 0
src/PixiEditor.Extensions.Sdk/PixiEditorExtension.cs

@@ -13,4 +13,10 @@ public abstract class PixiEditorExtension
     ///     Called when extension is initialized. Api is initialized and ready to use.
     /// </summary>
     public virtual void OnInitialized() { }
+
+    /// <summary>
+    ///     Called when the user is ready to use the application. This is called when startup screen would be shown to the user.
+    /// If user didn't complete onboarding, it will be called after the user completes it.
+    /// </summary>
+    public virtual void OnUserReady() { }
 }

+ 6 - 0
src/PixiEditor.Extensions.WasmRuntime/WasmExtensionInstance.cs

@@ -75,6 +75,12 @@ public partial class WasmExtensionInstance : Extension
         base.OnInitialized();
     }
 
+    protected override void OnUserReady()
+    {
+        Instance.GetAction("user_ready").Invoke();
+        base.OnUserReady();
+    }
+
     private void OnAsyncCallCompleted(int handle, int result)
     {
         Dispatcher.UIThread.Invoke(() =>

+ 14 - 0
src/PixiEditor.Extensions/Extension.cs

@@ -35,6 +35,11 @@ public abstract class Extension
         OnInitialized();
     }
 
+    public void UserReady()
+    {
+        OnUserReady();
+    }
+
     /// <summary>
     ///     Called right after the extension is loaded. Not all extensions are initialized at this point. PixiEditor API at this point is not available.
     ///     Use this method to load resources, patch language files, etc.
@@ -49,4 +54,13 @@ public abstract class Extension
     protected virtual void OnInitialized()
     {
     }
+
+    /// <summary>
+    ///     Called after OnInitialized. It is called when startup screen should be shown to the user.
+    /// If the user didn't complete onboarding, it will be called after the user completes it.
+    /// </summary>
+    protected virtual void OnUserReady()
+    {
+
+    }
 }

+ 6 - 0
src/PixiEditor/ViewModels/SubViewModels/ExtensionsViewModel.cs

@@ -22,6 +22,7 @@ internal class ExtensionsViewModel : SubViewModel<ViewModelMain>
         WindowProvider windowProvider = (WindowProvider)Owner.Services.GetService<IWindowProvider>();
         RegisterCoreWindows(windowProvider);
         Owner.OnEarlyStartupEvent += Owner_OnEarlyStartupEvent;
+        Owner.OnUserReady += Owner_OnUserReady;
     }
 
     public void LoadExtensionAdHoc(string extension)
@@ -48,4 +49,9 @@ internal class ExtensionsViewModel : SubViewModel<ViewModelMain>
     {
         ExtensionLoader.InitializeExtensions(new ExtensionServices(Owner.Services));
     }
+
+    private void Owner_OnUserReady()
+    {
+        ExtensionLoader.InvokeOnUserReady();
+    }
 }

+ 9 - 1
src/PixiEditor/ViewModels/SubViewModels/FileViewModel.cs

@@ -153,12 +153,20 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             if (preferences.GetLocalPreference("OnboardingV2Shown", false) == false)
             {
                 preferences.UpdateLocalPreference("OnboardingV2Shown", true);
-                Owner.WindowSubViewModel.OpenOnboardingWindow();
+                Owner.WindowSubViewModel.OpenOnboardingWindow().Closed += (sender, eventArgs) =>
+                {
+                    Owner.InvokeUserReadyEvent();
+                };
             }
             else if (preferences!.GetPreference("ShowStartupWindow", true))
             {
+                Owner.InvokeUserReadyEvent();
                 OpenHelloTherePopup();
             }
+            else
+            {
+                Owner.InvokeUserReadyEvent();
+            }
         }
     }
 

+ 4 - 2
src/PixiEditor/ViewModels/SubViewModels/WindowViewModel.cs

@@ -256,9 +256,11 @@ internal class WindowViewModel : SubViewModel<ViewModelMain>, IWindowHandler
     [Command.Basic("PixiEditor.Window.OpenOnboardingWindow", "OPEN_ONBOARDING_WINDOW", "OPEN_ONBOARDING_WINDOW",
         Icon = PixiPerfectIcons.Compass, MenuItemPath = "VIEW/OPEN_ONBOARDING_WINDOW", MenuItemOrder = 2,
         AnalyticsTrack = true)]
-    public void OpenOnboardingWindow()
+    public OnboardingDialog OpenOnboardingWindow()
     {
-        new OnboardingDialog { DataContext = new OnboardingViewModel() }.ShowDialog(MainWindow.Current);
+        var dialog = new OnboardingDialog { DataContext = new OnboardingViewModel() };
+        dialog.ShowDialog(MainWindow.Current);
+        return dialog;
     }
 
     [Commands_Command.Basic("PixiEditor.Window.OpenShortcutWindow", "OPEN_SHORTCUT_WINDOW", "OPEN_SHORTCUT_WINDOW",

+ 6 - 0
src/PixiEditor/ViewModels/ViewModelMain.cs

@@ -96,6 +96,7 @@ internal partial class ViewModelMain : ViewModelBase, ICommandsHandler
     public bool UserWantsToClose { get; private set; }
     public Guid CurrentSessionId { get; } = Guid.NewGuid();
     public DateTime LaunchDateTime { get; } = DateTime.Now;
+    public event Action OnUserReady;
 
     public event Action<DocumentViewModel> BeforeDocumentClosed;
     public event Action<LazyDocumentViewModel> LazyDocumentClosed;
@@ -408,4 +409,9 @@ internal partial class ViewModelMain : ViewModelBase, ICommandsHandler
     {
         AttachedToWindow?.Invoke(mainWindow);
     }
+
+    internal void InvokeUserReadyEvent()
+    {
+        OnUserReady?.Invoke();
+    }
 }