From 0a222190800e7801ca297f66da767e71dfcf2de9 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Tue, 7 Jan 2025 06:40:52 -0600 Subject: [PATCH] Allow CommandProviders to ItemsChanged themselves (#282) Specs out #277 Extensions might want to change their list of top-level commands. Classic example is the bookmarks provider, or the spongebot. The API needs to allow this. This wasn't a problem in the prototype, because the prototype literally fetched the commands every time it went home. --- .../doc/initial-sdk-spec/initial-sdk-spec.md | 10 +++++++++- .../CommandProvider.cs | 15 +++++++++++++++ .../Microsoft.CmdPal.Extensions.idl | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md b/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md index 9c9ed2c18c..040b20569a 100644 --- a/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md +++ b/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md @@ -1371,7 +1371,7 @@ interface IFallbackCommandItem requires ICommandItem { IFallbackHandler FallbackHandler{ get; }; }; -interface ICommandProvider requires Windows.Foundation.IClosable +interface ICommandProvider requires Windows.Foundation.IClosable, INotifyItemsChanged { String Id { get; }; String DisplayName { get; }; @@ -1397,6 +1397,14 @@ actions, or they can be pages that the user can navigate to. simpler form of `IListItem`, which can be displayed even as a stub (as described in [Caching](#caching)), before the extension process is loaded. +The `INotifyItemsChanged` interface can be used to let DevPal know at runtime +that the list of top-level command items has changed. This can be used for +something like an extension that might require the user to login before +accessing certain pages within the extension. Command Providers which are +`Frozen=true` can also use this event to change their list of cached commands, +since the only time an extension can raise this event is when it's already +running. + `Id` is only necessary to set if your extension implements multiple providers in the same package identity. This is an uncommon scenario which most developers shouldn't need to worry about. If you do set `Id`, it should be a stable string diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs index 53dc78d88f..aac0febea0 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs @@ -2,6 +2,8 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Windows.Foundation; + namespace Microsoft.CmdPal.Extensions.Helpers; public abstract partial class CommandProvider : ICommandProvider @@ -20,6 +22,8 @@ public abstract partial class CommandProvider : ICommandProvider public IconDataType Icon { get => _icon; protected set => _icon = value; } + public event TypedEventHandler? ItemsChanged; + public abstract ICommandItem[] TopLevelCommands(); public virtual IFallbackCommandItem[]? FallbackCommands() @@ -47,4 +51,15 @@ public abstract partial class CommandProvider : ICommandProvider } #pragma warning restore CA1816 // Dispose methods should call SuppressFinalize + protected void RaiseItemsChanged(int totalItems) + { + try + { + // TODO #181 - This is the same thing that BaseObservable has to deal with. + ItemsChanged?.Invoke(this, new ItemsChangedEventArgs(totalItems)); + } + catch + { + } + } } diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl index 4138e2add0..dd56479588 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl @@ -311,7 +311,7 @@ namespace Microsoft.CmdPal.Extensions }; [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] - interface ICommandProvider requires Windows.Foundation.IClosable + interface ICommandProvider requires Windows.Foundation.IClosable, INotifyItemsChanged { String Id { get; }; String DisplayName { get; };