diff --git a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/Pages/TemplateExtensionPage.cs b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/Pages/TemplateCmdPalExtensionPage.cs similarity index 100% rename from src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/Pages/TemplateExtensionPage.cs rename to src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/TemplateCmdPalExtension/Pages/TemplateCmdPalExtensionPage.cs diff --git a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/deps/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.0.0.5.nupkg b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/deps/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.0.0.5.nupkg deleted file mode 100644 index ba9079f60263..000000000000 Binary files a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/deps/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.0.0.5.nupkg and /dev/null differ diff --git a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/nuget.config b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/nuget.config index 2f9ebc93c1ac..e6a17ffdfed7 100644 --- a/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/nuget.config +++ b/src/modules/cmdpal/ExtensionTemplate/TemplateCmdPalExtension/nuget.config @@ -3,14 +3,10 @@ - - - - diff --git a/src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/ExtensionHostInstance.cs b/src/modules/cmdpal/Microsoft.CmdPal.Common/Helpers/ExtensionHostInstance.cs similarity index 96% rename from src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/ExtensionHostInstance.cs rename to src/modules/cmdpal/Microsoft.CmdPal.Common/Helpers/ExtensionHostInstance.cs index ba46cc0bd5e8..c736eea123a8 100644 --- a/src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/ExtensionHostInstance.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.Common/Helpers/ExtensionHostInstance.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation +// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -7,7 +7,7 @@ using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; -namespace Microsoft.CmdPal.Ext.WinGet; +namespace Microsoft.CmdPal.Common; public partial class ExtensionHostInstance { diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Assets/template.zip b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Assets/template.zip new file mode 100644 index 000000000000..398512fd492b Binary files /dev/null and b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Assets/template.zip differ diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs index e94c77c4701a..db55670be464 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs @@ -2,7 +2,6 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CmdPal.UI.ViewModels.Commands; using Microsoft.CmdPal.UI.ViewModels.Messages; using Microsoft.CommandPalette.Extensions; using Microsoft.CommandPalette.Extensions.Toolkit; @@ -18,10 +17,12 @@ public partial class BuiltInsCommandProvider : CommandProvider private readonly QuitCommand quitCommand = new(); private readonly FallbackReloadItem _fallbackReloadItem = new(); private readonly FallbackLogItem _fallbackLogItem = new(); + private readonly NewExtensionPage _newExtension = new(); public override ICommandItem[] TopLevelCommands() => [ new CommandItem(openSettings) { Subtitle = "Open Command Palette settings" }, + new CommandItem(_newExtension) { Title = _newExtension.Title, Subtitle = "Creates a project for a new Command Palette extension" }, ]; public override IFallbackCommandItem[] FallbackCommands() => @@ -37,4 +38,6 @@ public BuiltInsCommandProvider() DisplayName = "Built-in commands"; Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.scale-200.png"); } + + public override void InitializeWithHost(IExtensionHost host) => BuiltinsExtensionHost.Instance.Initialize(host); } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltinsExtensionHost.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltinsExtensionHost.cs new file mode 100644 index 000000000000..f643f0fc848a --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltinsExtensionHost.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.IO.Compression; +using System.Text.Json; +using System.Text.Json.Nodes; +using Microsoft.CmdPal.Common; +using Microsoft.CmdPal.UI.ViewModels.Messages; +using Microsoft.CommandPalette.Extensions; +using Microsoft.CommandPalette.Extensions.Toolkit; +using Windows.Foundation; + +namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands; + +public partial class BuiltinsExtensionHost +{ + internal static ExtensionHostInstance Instance { get; } = new(); +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/CreatedExtensionForm.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/CreatedExtensionForm.cs new file mode 100644 index 000000000000..d2cd61788e1b --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/CreatedExtensionForm.cs @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.IO.Compression; +using System.Text.Json; +using System.Text.Json.Nodes; +using Microsoft.CmdPal.UI.ViewModels.Messages; +using Microsoft.CommandPalette.Extensions; +using Microsoft.CommandPalette.Extensions.Toolkit; +using Windows.Foundation; + +namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands; + +internal sealed partial class CreatedExtensionForm : NewExtensionFormBase +{ + public CreatedExtensionForm(string name, string displayName, string path) + { + TemplateJson = CardTemplate; + DataJson = $$""" +{ + "name": {{JsonSerializer.Serialize(name)}}, + "directory": {{JsonSerializer.Serialize(path)}}, + "displayName": {{JsonSerializer.Serialize(displayName)}} +} +"""; + _name = name; + _displayName = displayName; + _path = path; + } + + public override ICommandResult SubmitForm(string inputs, string data) + { + var dataInput = JsonNode.Parse(data)?.AsObject(); + if (dataInput == null) + { + return CommandResult.KeepOpen(); + } + + var verb = dataInput["x"]?.AsValue()?.ToString() ?? string.Empty; + return verb switch + { + "sln" => OpenSolution(), + "dir" => OpenDirectory(), + "new" => CreateNew(), + _ => CommandResult.KeepOpen(), + }; + } + + private ICommandResult OpenSolution() + { + string[] parts = [_path, _name, $"{_name}.sln"]; + var pathToSolution = Path.Combine(parts); + ShellHelpers.OpenInShell(pathToSolution); + return CommandResult.GoHome(); + } + + private ICommandResult OpenDirectory() + { + string[] parts = [_path, _name]; + var pathToDir = Path.Combine(parts); + ShellHelpers.OpenInShell(pathToDir); + return CommandResult.GoHome(); + } + + private ICommandResult CreateNew() + { + RaiseFormSubmit(null); + return CommandResult.KeepOpen(); + } + + private static readonly string CardTemplate = """ +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.6", + "body": [ + { + "type": "TextBlock", + "text": "Successfully created your new extension!", + "size": "large", + "weight": "bolder", + "style": "heading", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Your new extension \"${displayName}\" was created in:", + "wrap": true + }, + { + "type": "TextBlock", + "text": "${directory}", + "fontType": "monospace" + }, + { + "type": "TextBlock", + "text": "Next steps", + "style": "heading", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Now that your extension project has been created, open the solution up in Visual Studio to start writing your extension code.", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Navigate to `${name}Page.cs` to start adding items to the list, or to `${name}CommandsProvider.cs` to add new commands.", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Once you're ready to test deploy the package locally with Visual Studio, then run the \"Reload\" command in the Command Palette to load your new extension.", + "wrap": true + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Open Solution", + "data": { + "x": "sln" + } + }, + { + "type": "Action.Submit", + "title": "Open directory", + "data": { + "x": "dir" + } + }, + { + "type": "Action.Submit", + "title": "Create another", + "data": { + "x": "new" + } + } + ] +} +"""; + + private readonly string _name; + private readonly string _displayName; + private readonly string _path; +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionForm.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionForm.cs new file mode 100644 index 000000000000..320921d77817 --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionForm.cs @@ -0,0 +1,216 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO.Compression; +using System.Text.Json.Nodes; +using Microsoft.CommandPalette.Extensions; +using Microsoft.CommandPalette.Extensions.Toolkit; + +namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands; + +internal sealed partial class NewExtensionForm : NewExtensionFormBase +{ + private static readonly string _creatingText = "Creating new extension..."; + private readonly StatusMessage _creatingMessage = new() + { + Message = _creatingText, + Progress = new ProgressState() { IsIndeterminate = true }, + }; + + public NewExtensionForm() + { + TemplateJson = $$""" +{ + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.6", + "body": [ + { + "type": "TextBlock", + "text": "Create your new extension", + "size": "large" + }, + { + "type": "TextBlock", + "text": "Use this page to create a new extension project.", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Extension name", + "weight": "bolder", + "size": "default" + }, + { + "type": "TextBlock", + "text": "This is the name of your new extension project. It should be a valid C# class name. Best practice is to also include the word 'Extension' in the name.", + "wrap": true + }, + { + "type": "Input.Text", + "label": "Extension name", + "isRequired": true, + "errorMessage": "Extension name is required, without spaces", + "id": "ExtensionName", + "placeholder": "ExtensionName", + "regex": "^[^\\s]+$" + }, + { + "type": "TextBlock", + "text": "Display name", + "weight": "bolder", + "size": "default" + }, + { + "type": "TextBlock", + "text": "The name of your extension as users will see it.", + "wrap": true + }, + { + "type": "Input.Text", + "label": "Display name", + "isRequired": true, + "errorMessage": "Display name is required", + "id": "DisplayName", + "placeholder": "My new extension" + }, + { + "type": "TextBlock", + "text": "Output path", + "weight": "bolder", + "size": "default" + }, + { + "type": "TextBlock", + "text": "Where should the new extension be created? This path will be created if it doesn't exist", + "wrap": true + }, + { + "type": "Input.Text", + "label": "Output path", + "isRequired": true, + "errorMessage": "Output path is required", + "id": "OutputPath", + "placeholder": "C:\\users\\me\\dev" + } + ], + "actions": [ + { + "type": "Action.Submit", + "title": "Create extension", + "associatedInputs": "auto" + } + ] +} +"""; + } + + public override CommandResult SubmitForm(string payload) + { + var formInput = JsonNode.Parse(payload)?.AsObject(); + if (formInput == null) + { + return CommandResult.KeepOpen(); + } + + var extensionName = formInput["ExtensionName"]?.AsValue()?.ToString() ?? string.Empty; + var displayName = formInput["DisplayName"]?.AsValue()?.ToString() ?? string.Empty; + var outputPath = formInput["OutputPath"]?.AsValue()?.ToString() ?? string.Empty; + + _creatingMessage.State = MessageState.Info; + _creatingMessage.Message = _creatingText; + _creatingMessage.Progress = new ProgressState() { IsIndeterminate = true }; + BuiltinsExtensionHost.Instance.ShowStatus(_creatingMessage); + + try + { + CreateExtension(extensionName, displayName, outputPath); + + // _creatingMessage.Progress = null; + // _creatingMessage.State = MessageState.Success; + // _creatingMessage.Message = $"Successfully created extension"; + BuiltinsExtensionHost.Instance.HideStatus(_creatingMessage); + + // BuiltinsExtensionHost.Instance.HideStatus(_creatingMessage); + RaiseFormSubmit(new CreatedExtensionForm(extensionName, displayName, outputPath)); + + // _toast.Message.State = MessageState.Success; + // _toast.Message.Message = $"Successfully created extension"; + // _toast.Show(); + } + catch (Exception e) + { + BuiltinsExtensionHost.Instance.HideStatus(_creatingMessage); + + _creatingMessage.State = MessageState.Error; + _creatingMessage.Message = $"Error: {e.Message}"; + + // _toast.Show(); + } + + // _ = Task.Run(() => + // { + // Thread.Sleep(2500); + // BuiltinsExtensionHost.Instance.HideStatus(_creatingMessage); + // }); + return CommandResult.KeepOpen(); + } + + private void CreateExtension(string extensionName, string newDisplayName, string outputPath) + { + var newGuid = Guid.NewGuid().ToString(); + + // Unzip `template.zip` to a temp dir: + var tempDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + + // Console.WriteLine($"Extracting to {tempDir}"); + + // Does the output path exist? + if (!Directory.Exists(outputPath)) + { + Directory.CreateDirectory(outputPath); + } + + var assetsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.ToString(), "Microsoft.CmdPal.UI.ViewModels\\Assets\\template.zip"); + ZipFile.ExtractToDirectory(assetsPath, tempDir); + + var files = Directory.GetFiles(tempDir, "*", SearchOption.AllDirectories); + foreach (var file in files) + { + var text = File.ReadAllText(file); + + Console.WriteLine($" Processing {file}"); + + // Replace all the instances of `FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF` with a new random guid: + text = text.Replace("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF", newGuid); + + // Then replace all the `TemplateCmdPalExtension` with `extensionName` + text = text.Replace("TemplateCmdPalExtension", extensionName); + + // Then replace all the `TemplateDisplayName` with `newDisplayName` + text = text.Replace("TemplateDisplayName", newDisplayName); + + // We're going to write the file to the same relative location in the output path + var relativePath = Path.GetRelativePath(tempDir, file); + + var newFileName = Path.Combine(outputPath, relativePath); + + // if the file name had `TemplateCmdPalExtension` in it, replace it with `extensionName` + newFileName = newFileName.Replace("TemplateCmdPalExtension", extensionName); + + // Make sure the directory exists + Directory.CreateDirectory(Path.GetDirectoryName(newFileName)!); + + File.WriteAllText(newFileName, text); + + Console.WriteLine($" Wrote {newFileName}"); + + // Delete the old file + File.Delete(file); + } + + // Delete the temp dir + Directory.Delete(tempDir, true); + } +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionFormBase.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionFormBase.cs new file mode 100644 index 000000000000..e68fef10a41e --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionFormBase.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using System.IO.Compression; +using System.Text.Json; +using System.Text.Json.Nodes; +using Microsoft.CmdPal.UI.ViewModels.Messages; +using Microsoft.CommandPalette.Extensions; +using Microsoft.CommandPalette.Extensions.Toolkit; +using Windows.Foundation; + +namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands; + +internal abstract partial class NewExtensionFormBase : FormContent +{ + public event TypedEventHandler? FormSubmitted; + + protected void RaiseFormSubmit(NewExtensionFormBase? next) => FormSubmitted?.Invoke(this, next); +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionPage.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionPage.cs new file mode 100644 index 000000000000..2f0055b5f260 --- /dev/null +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/NewExtensionPage.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CommandPalette.Extensions; +using Microsoft.CommandPalette.Extensions.Toolkit; + +namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands; + +public partial class NewExtensionPage : ContentPage +{ + private NewExtensionForm _inputForm = new(); + private NewExtensionFormBase? _resultForm; + + public override IContent[] GetContent() + { + return _resultForm != null ? [_resultForm] : [_inputForm]; + } + + public NewExtensionPage() + { + Name = "Open"; + Title = "Create a new extension"; + Icon = new IconInfo("\uEA86"); // Puzzle + + _inputForm.FormSubmitted += FormSubmitted; + } + + private void FormSubmitted(NewExtensionFormBase sender, NewExtensionFormBase? args) + { + if (_resultForm != null) + { + _resultForm.FormSubmitted -= FormSubmitted; + } + + _resultForm = args; + if (_resultForm != null) + { + _resultForm.FormSubmitted += FormSubmitted; + } + else + { + _inputForm = new(); + _inputForm.FormSubmitted += FormSubmitted; + } + + RaiseItemsChanged(1); + } +} diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ContentFormViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ContentFormViewModel.cs index 1247b3939d5a..a148576bf136 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ContentFormViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ContentFormViewModel.cs @@ -83,19 +83,22 @@ public void HandleSubmit(IAdaptiveActionElement action, JsonObject inputs) var dataString = (action as AdaptiveSubmitAction)?.DataJson.Stringify() ?? string.Empty; var inputString = inputs.Stringify(); - try + _ = Task.Run(() => { - var model = _formModel.Unsafe!; - if (model != null) + try { - var result = model.SubmitForm(inputString, dataString); - WeakReferenceMessenger.Default.Send(new(new(result))); + var model = _formModel.Unsafe!; + if (model != null) + { + var result = model.SubmitForm(inputString, dataString); + WeakReferenceMessenger.Default.Send(new(new(result))); + } } - } - catch (Exception ex) - { - PageContext.ShowException(ex); - } + catch (Exception ex) + { + PageContext.ShowException(ex); + } + }); } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj index ce02d54414c2..c3058f39b496 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Microsoft.CmdPal.UI.ViewModels.csproj @@ -34,4 +34,8 @@ + + + + diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs index 02bec2921180..02cb9d64976a 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/App.xaml.cs @@ -85,7 +85,6 @@ private static ServiceProvider ConfigureServices() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -94,6 +93,7 @@ private static ServiceProvider ConfigureServices() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); // Models services.AddSingleton(); diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml index 6dea9252baa4..3d37c550dbaf 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/CommandBar.xaml @@ -20,6 +20,10 @@ x:Key="StringNotEmptyToVisibilityConverter" EmptyValue="Collapsed" NotEmptyValue="Visible" /> + @@ -65,7 +69,8 @@ + Tapped="PageIcon_Tapped" + Visibility="{x:Bind CurrentPageViewModel.IsNested, Mode=OneWay}"> + + Text="{x:Bind CurrentPageViewModel.Title, Mode=OneWay}" + Visibility="{x:Bind CurrentPageViewModel.IsNested, Mode=OneWay}" /> (); + e.Handled = true; + } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml index f29e940850ff..48784a997f38 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml @@ -1,4 +1,4 @@ - + - - + + diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml.cs index 89a218bffdc1..5ae1a4da6a3a 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ContentFormControl.xaml.cs @@ -24,7 +24,13 @@ public sealed partial class ContentFormControl : UserControl static ContentFormControl() { - _renderer = new AdaptiveCardRenderer(); + // We can't use `CardOverrideStyles` here yet, because we haven't called InitializeComponent once. + // But also, the default value isn't `null` here. It's... some other default empty value. + // So clear it out so that we know when the first time we get created is + _renderer = new AdaptiveCardRenderer() + { + OverrideStyles = null, + }; } public ContentFormControl() @@ -33,6 +39,14 @@ public ContentFormControl() var lightTheme = ActualTheme == Microsoft.UI.Xaml.ElementTheme.Light; _renderer.HostConfig = lightTheme ? AdaptiveCardsConfig.Light : AdaptiveCardsConfig.Dark; + // 5% bodgy: if we set this multiple times over the lifetime of the app, + // then the second call will explode, because "CardOverrideStyles is already the child of another element". + // SO only set this once. + if (_renderer.OverrideStyles == null) + { + _renderer.OverrideStyles = CardOverrideStyles; + } + // TODO in the future, we should handle ActualThemeChanged and replace // our rendered card with one for that theme. But today is not that day } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml index 9371636428a4..54de7967b5ba 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SearchBar.xaml @@ -50,7 +50,7 @@ VerticalAlignment="Center" FontSize="8" Foreground="{ThemeResource TextFillColorSecondaryBrush}" - Glyph="" /> + Glyph="" /> + + + PreserveNewest + + MSBuild:Compile diff --git a/src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj b/src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj index 3e7a7c8d7205..2f5d8d8f13eb 100644 --- a/src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj +++ b/src/modules/cmdpal/exts/Microsoft.CmdPal.Ext.WinGet/Microsoft.CmdPal.Ext.WinGet.csproj @@ -27,7 +27,8 @@ - + +