Merge pull request #28 from zadjii-msft/dev/crutkas/fixMore

lotta more fixes
This commit is contained in:
Clint Rutkas
2024-09-04 07:15:40 -07:00
committed by GitHub
17 changed files with 270 additions and 243 deletions

View File

@@ -47,7 +47,6 @@ internal sealed class OpenInTerminalAction : InvokableCommand
}
}
internal sealed class BookmarkData
{
internal string name = string.Empty;
@@ -150,8 +149,6 @@ internal sealed class AddBookmarkForm : Form
bookmarkType = "web";
}
// Construct a new json blob with the name and url
var json = string.Empty;
@@ -180,7 +177,8 @@ internal sealed class AddBookmarkForm : Form
json = jsonState?.ToString();
}
}
else {
else
{
json = $$"""
{
"items": [
@@ -199,7 +197,6 @@ internal sealed class AddBookmarkForm : Form
AddedAction?.Invoke(this, null);
return ActionResult.GoHome();
}
}
internal sealed class AddBookmarkPage : Microsoft.Windows.CommandPalette.Extensions.Helpers.FormPage
@@ -280,6 +277,7 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
public override ActionResult SubmitForm(string payload)
{
var target = _Bookmark;
// parse the submitted JSON and then open the link
var formInput = JsonNode.Parse(payload);
var formObject = formInput?.AsObject();
@@ -297,7 +295,6 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
try
{
Uri? uri = UrlAction.GetUri(target);
if (uri != null)
{
@@ -315,7 +312,6 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
return ActionResult.GoHome();
}
}
internal sealed class BookmarkPlaceholderPage : Microsoft.Windows.CommandPalette.Extensions.Helpers.FormPage
@@ -384,6 +380,7 @@ public class UrlAction : InvokableCommand
return null;
}
}
return uri;
}
@@ -414,12 +411,12 @@ public class UrlAction : InvokableCommand
{
// return "🔗";
}
return "🔗";
}
}
}
public class BookmarksActionProvider : ICommandProvider
{
public string DisplayName => $"Bookmarks";
@@ -432,17 +429,14 @@ public class BookmarksActionProvider : ICommandProvider
public BookmarksActionProvider()
{
_addNewCommand.AddedAction += _addNewCommand_AddedAction;
}
private void _addNewCommand_AddedAction(object sender, object? args)
{
_addNewCommand.AddedAction += _addNewCommand_AddedAction;
_commands.Clear();
}
#pragma warning disable CA1816 // Dispose methods should call SuppressFinalize
public void Dispose() => throw new NotImplementedException();
#pragma warning restore CA1816 // Dispose methods should call SuppressFinalize
@@ -455,8 +449,8 @@ public class BookmarksActionProvider : ICommandProvider
{
// Open state.json from the disk and read it
var state = File.ReadAllText(BookmarksActionProvider.StateJsonPath());
// Parse the JSON
// Parse the JSON
var json = JsonNode.Parse(state);
var jsonObject = json?.AsObject();
if (jsonObject == null)
@@ -464,13 +458,16 @@ public class BookmarksActionProvider : ICommandProvider
return;
}
if (!jsonObject.ContainsKey("items"))
{
return;
}
var itemsJson = jsonObject["items"]?.AsArray();
if (itemsJson == null) { return; }
if (itemsJson == null)
{
return;
}
foreach (var item in itemsJson)
{
@@ -481,6 +478,7 @@ public class BookmarksActionProvider : ICommandProvider
{
continue;
}
var name = nameToken.ToString();
var url = urlToken.ToString();
var type = typeToken.ToString();
@@ -493,7 +491,6 @@ public class BookmarksActionProvider : ICommandProvider
Console.WriteLine($"Error loading commands: {ex.Message}");
}
_commands.Clear();
_commands.AddRange(collected);
}
@@ -504,6 +501,7 @@ public class BookmarksActionProvider : ICommandProvider
{
LoadCommands();
}
return _commands.Select(action =>
{
var listItem = new ListItem(action);
@@ -515,21 +513,24 @@ public class BookmarksActionProvider : ICommandProvider
new CommandContextItem(new OpenInTerminalAction(urlAction.Url))
];
}
//listItem.Subtitle = "Bookmark";
// listItem.Subtitle = "Bookmark";
if (action is AddBookmarkPage) { }
else
{
listItem.Tags = [
new Tag() {
Text = "Bookmark",
//Icon = new("🔗"),
//Color=Windows.UI.Color.FromArgb(255, 255, 0, 255)
// Icon = new("🔗"),
// Color=Windows.UI.Color.FromArgb(255, 255, 0, 255)
},
//new Tag() {
// new Tag() {
// Text = "A test",
// //Icon = new("🔗"),
// Color=Windows.UI.Color.FromArgb(255, 255, 0, 0)
//}
// }
];
}
@@ -541,10 +542,11 @@ public class BookmarksActionProvider : ICommandProvider
{
// Get the path to our exe
var path = System.Reflection.Assembly.GetExecutingAssembly().Location;
// Get the directory of the exe
var directory = System.IO.Path.GetDirectoryName(path) ?? string.Empty;
// now, the state is just next to the exe
return System.IO.Path.Combine(directory, "state.json");
}
}

View File

@@ -12,7 +12,7 @@ namespace WindowsCommandPalette.BuiltinCommands.AllApps;
public sealed class AllAppsPage : ListPage
{
private ISection allAppsSection;
private ISection allAppsSection = new ListSection();
public AllAppsPage()
{
@@ -26,27 +26,22 @@ public sealed class AllAppsPage : ListPage
public override ISection[] GetItems()
{
if (this.allAppsSection == null)
if (this.allAppsSection == null || allAppsSection.Items.Length == 0)
{
PopulateApps();
var apps = GetPrograms();
this.Loading = false;
this.allAppsSection = new ListSection()
{
Title = "Apps",
Items = apps
.Select((app) => new AppListItem(app))
.ToArray(),
};
}
return [allAppsSection];
}
private void PopulateApps()
{
var apps = GetPrograms();
this.Loading = false;
this.allAppsSection = new ListSection()
{
Title = "Apps",
Items = apps
.Select((app) => new AppListItem(app))
.ToArray(),
};
}
internal static List<AppItem> GetPrograms()
{
// NOTE TO SELF:

View File

@@ -1,37 +0,0 @@
// 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;
using System.IO.Abstractions;
namespace WindowsCommandPalette.BuiltinCommands.AllApps;
public class FileVersionInfoWrapper : IFileVersionInfoWrapper
{
private readonly IFile _file;
public FileVersionInfoWrapper()
: this(new FileSystem().File)
{
}
public FileVersionInfoWrapper(IFile file)
{
_file = file;
}
public FileVersionInfo GetVersionInfo(string path)
{
if (_file.Exists(path))
{
return FileVersionInfo.GetVersionInfo(path);
}
else
{
return null;
}
}
public string FileDescription { get; set; }
}

View File

@@ -1,14 +0,0 @@
// 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;
namespace WindowsCommandPalette.BuiltinCommands.AllApps;
public interface IFileVersionInfoWrapper
{
FileVersionInfo GetVersionInfo(string path);
string FileDescription { get; set; }
}

View File

@@ -2,10 +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 System;
using System.IO;
using System.Reflection;
// using Microsoft.Plugin.Program.Logger;
using Windows.Foundation.Metadata;
using Package = Windows.ApplicationModel.Package;
@@ -39,7 +35,7 @@ public class PackageWrapper : IPackage
InstalledLocation = installedLocation;
}
private static readonly Lazy<bool> IsPackageDotInstallationPathAvailable = new (() =>
private static readonly Lazy<bool> IsPackageDotInstallationPathAvailable = new(() =>
ApiInformation.IsPropertyPresent(typeof(Package).FullName, nameof(Package.InstalledLocation.Path)));
public static PackageWrapper GetWrapperFromPackage(Package package)
@@ -53,7 +49,7 @@ public class PackageWrapper : IPackage
}
catch (Exception e) when (e is ArgumentException || e is FileNotFoundException || e is DirectoryNotFoundException)
{
//ProgramLogger.Exception($"Exception {package.Id.Name}", e, MethodBase.GetCurrentMethod().DeclaringType, "Path could not be determined");
// ProgramLogger.Exception($"Exception {package.Id.Name}", e, MethodBase.GetCurrentMethod().DeclaringType, "Path could not be determined");
return new PackageWrapper(
package.Id.Name,
package.Id.FullName,
@@ -75,4 +71,4 @@ public class PackageWrapper : IPackage
// This is a separate method so the reference to .InstalledPath won't be loaded in API versions which do not support this API (e.g. older then Build 19041)
private static string GetInstalledPath(Package package)
=> package.InstalledLocation.Path;
}
}

View File

@@ -14,15 +14,11 @@ namespace AllApps.Programs;
/// </remarks>
public class ProgramSource
{
//private static readonly IFileSystem FileSystem = new FileSystem();
public string Location { get; set; } = string.Empty;
private string name;
public string Location { get; set; }
public string Name { get => name ?? "" /*FileSystem.DirectoryInfo.FromDirectoryName(Location).Name*/; set => name = value; }
public string Name { get; set; } = string.Empty;
public bool Enabled { get; set; } = true;
public string UniqueIdentifier { get; set; }
}
public string UniqueIdentifier { get; set; } = string.Empty;
}

View File

@@ -27,12 +27,12 @@ public partial class UWP
public string FamilyName { get; }
public string Location { get; set; }
public string Location { get; set; } = string.Empty;
// Localized path based on windows display language
public string LocationLocalized { get; set; }
public string LocationLocalized { get; set; } = string.Empty;
public IList<UWPApplication> Apps { get; private set; }
public IList<UWPApplication> Apps { get; private set; } = new List<UWPApplication>();
public PackageVersion Version { get; set; }
@@ -172,7 +172,7 @@ public partial class UWP
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1309:Use ordinal string comparison", Justification = "Using CurrentCultureIgnoreCase since this is used with FamilyName")]
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
if (obj is UWP uwp)
{

View File

@@ -17,19 +17,19 @@ public class UWPApplication : IProgram
private static readonly IPath Path = FileSystem.Path;
private static readonly IFile File = FileSystem.File;
public string AppListEntry { get; set; }
public string AppListEntry { get; set; } = string.Empty;
public string UniqueIdentifier { get; set; }
public string UniqueIdentifier { get; set; } = string.Empty;
public string DisplayName { get; set; }
public string DisplayName { get; set; } = string.Empty;
public string Description { get; set; }
public string Description { get; set; } = string.Empty;
public string UserModelId { get; set; }
public string UserModelId { get; set; } = string.Empty;
public string BackgroundColor { get; set; }
public string BackgroundColor { get; set; } = string.Empty;
public string EntryPoint { get; set; }
public string EntryPoint { get; set; } = string.Empty;
public string Name => DisplayName;
@@ -42,7 +42,7 @@ public class UWPApplication : IProgram
public bool CanRunElevated { get; set; }
public string LogoPath { get; set; }
public string LogoPath { get; set; } = string.Empty;
public LogoType LogoType { get; set; }
@@ -112,13 +112,16 @@ public class UWPApplication : IProgram
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(file);
var xmlRoot = xmlDoc.DocumentElement;
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
var trustLevelNode = xmlRoot.SelectSingleNode("//*[local-name()='Application' and @uap10:TrustLevel]", namespaceManager); // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
if (trustLevelNode?.Attributes["uap10:TrustLevel"]?.Value == "mediumIL")
if (xmlRoot != null)
{
return true;
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("uap10", "http://schemas.microsoft.com/appx/manifest/uap/windows10/10");
var trustLevelNode = xmlRoot.SelectSingleNode("//*[local-name()='Application' and @uap10:TrustLevel]", namespaceManager); // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes
if (trustLevelNode?.Attributes?["uap10:TrustLevel"]?.Value == "mediumIL")
{
return true;
}
}
}
catch (Exception)

View File

@@ -18,34 +18,34 @@ public class Win32Program // : IProgram
Enabled = false,
};
public string Name { get; set; }
public string Name { get; set; } = string.Empty;
// Localized name based on windows display language
public string NameLocalized { get; set; } = string.Empty;
public string UniqueIdentifier { get; set; }
public string UniqueIdentifier { get; set; } = string.Empty;
public string IcoPath { get; set; }
public string IcoPath { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
// Path of app executable or lnk target executable
public string FullPath { get; set; }
public string FullPath { get; set; } = string.Empty;
// Localized path based on windows display language
public string FullPathLocalized { get; set; } = string.Empty;
public string ParentDirectory { get; set; }
public string ParentDirectory { get; set; } = string.Empty;
public string ExecutableName { get; set; }
public string ExecutableName { get; set; } = string.Empty;
// Localized executable name based on windows display language
public string ExecutableNameLocalized { get; set; } = string.Empty;
// Path to the lnk file on LnkProgram
public string LnkFilePath { get; set; }
public string LnkFilePath { get; set; } = string.Empty;
public string LnkResolvedExecutableName { get; set; }
public string LnkResolvedExecutableName { get; set; } = string.Empty;
// Localized path based on windows display language
public string LnkResolvedExecutableNameLocalized { get; set; } = string.Empty;
@@ -62,9 +62,6 @@ public class Win32Program // : IProgram
public ApplicationType AppType { get; set; }
// Wrappers for File Operations
public static IFileVersionInfoWrapper FileVersionInfoWrapper { get; set; } = new FileVersionInfoWrapper();
public static IShellLinkHelper ShellLinkHelper { get; set; } = new ShellLinkHelper();
private const string ShortcutExtension = "lnk";
@@ -188,6 +185,7 @@ public class Win32Program // : IProgram
{
try
{
var parDir = Directory.GetParent(path)?.FullName ?? string.Empty;
return new Win32Program
{
Name = Path.GetFileNameWithoutExtension(path),
@@ -197,7 +195,7 @@ public class Win32Program // : IProgram
// Using InvariantCulture since this is user facing
FullPath = path,
UniqueIdentifier = path,
ParentDirectory = Directory.GetParent(path).FullName,
ParentDirectory = parDir,
Description = string.Empty,
Valid = true,
Enabled = true,
@@ -264,7 +262,8 @@ public class Win32Program // : IProgram
}
else
{
var info = FileVersionInfoWrapper.GetVersionInfo(target);
var info = FileVersionInfo.GetVersionInfo(path);
if (!string.IsNullOrEmpty(info?.FileDescription))
{
program.Description = info.FileDescription;
@@ -294,7 +293,7 @@ public class Win32Program // : IProgram
try
{
var program = CreateWin32Program(path);
var info = FileVersionInfoWrapper.GetVersionInfo(path);
var info = FileVersionInfo.GetVersionInfo(path);
if (!string.IsNullOrEmpty(info?.FileDescription))
{
program.Description = info.FileDescription;
@@ -487,7 +486,7 @@ public class Win32Program // : IProgram
private static List<string> PathEnvironmentProgramPaths(IList<string> suffixes)
{
// To get all the locations stored in the PATH env variable
var pathEnvVariable = Environment.GetEnvironmentVariable("PATH");
var pathEnvVariable = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
var searchPaths = pathEnvVariable.Split(Path.PathSeparator);
var toFilterAllPaths = new List<string>();
var isRecursiveSearch = true;
@@ -593,18 +592,18 @@ public class Win32Program // : IProgram
}
}
private static string? ExpandEnvironmentVariables(string path)
private static string ExpandEnvironmentVariables(string path)
{
return path != null
? Environment.ExpandEnvironmentVariables(path)
: null;
: string.Empty;
}
// Overriding the object.GetHashCode() function to aid in removing duplicates while adding and removing apps from the concurrent dictionary storage
public override int GetHashCode()
=> Win32ProgramEqualityComparer.Default.GetHashCode(this);
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return obj is Win32Program win32Program && Win32ProgramEqualityComparer.Default.Equals(this, win32Program);
}
@@ -613,7 +612,7 @@ public class Win32Program // : IProgram
{
public static readonly Win32ProgramEqualityComparer Default = new();
public bool Equals(Win32Program app1, Win32Program app2)
public bool Equals(Win32Program? app1, Win32Program? app2)
{
if (app1 == null && app2 == null)
{
@@ -656,7 +655,7 @@ public class Win32Program // : IProgram
private static bool TryGetIcoPathForRunCommandProgram(Win32Program program, out string icoPath)
{
icoPath = null;
icoPath = string.Empty;
if (program.AppType != ApplicationType.RunCommand)
{
@@ -685,13 +684,12 @@ public class Win32Program // : IProgram
// ProgramLogger.Warn($"|Error whilst retrieving the redirection path from app execution alias {program.FullPath}", e, MethodBase.GetCurrentMethod().DeclaringType, program.FullPath);
}
icoPath = null;
return false;
}
private static Win32Program GetRunCommandProgramFromPath(string path)
{
var program = GetProgramFromPath(path);
var program = GetProgramFromPath(path) ?? new Win32Program();
program.AppType = ApplicationType.RunCommand;
if (TryGetIcoPathForRunCommandProgram(program, out var icoPath))

View File

@@ -12,7 +12,7 @@ namespace Calculator;
public class CalculatorAction : InvokableCommand
{
private bool _success;
private string _result;
private string _result = string.Empty;
public CalculatorAction()
{
@@ -33,6 +33,7 @@ public class CalculatorAction : InvokableCommand
{
_result = result;
_success = success;
if (success)
{
Name = "Copy";

View File

@@ -45,9 +45,10 @@ public class CalculatorTopLevelListItem : ListItem, IFallbackHandler
try
{
var result = new DataTable().Compute(equation, null);
var resultString = result.ToString();
var resultString = result.ToString() ?? string.Empty;
((CalculatorAction)Command).SetResult(resultString, true);
return result.ToString();
return resultString;
}
catch (Exception e)
{

View File

@@ -123,38 +123,32 @@ public sealed class ListItemViewModel : INotifyPropertyChanged, IDisposable
private void ListItem_PropertyChanged(object sender, Microsoft.Windows.CommandPalette.Extensions.PropChangedEventArgs args)
{
try{
try
{
var item = ListItem.Unsafe;
switch (args.PropertyName)
{
case "Name":
case nameof(Title):
{
this.Title = item.Title;
}
this.Title = item.Title;
break;
case nameof(Subtitle):
{
this.Subtitle = item.Subtitle;
}
this.Subtitle = item.Subtitle;
break;
case "MoreCommands":
{
BubbleXamlPropertyChanged(nameof(HasMoreCommands));
BubbleXamlPropertyChanged(nameof(ContextActions));
}
BubbleXamlPropertyChanged(nameof(HasMoreCommands));
BubbleXamlPropertyChanged(nameof(ContextActions));
break;
case nameof(Icon):
{
this.Icon = item.Command.Icon.Icon;
BubbleXamlPropertyChanged(nameof(IcoElement));
}
this.Icon = item.Command.Icon.Icon;
BubbleXamlPropertyChanged(nameof(IcoElement));
break;
}
BubbleXamlPropertyChanged(args.PropertyName);
} catch (COMException) {
}
catch (COMException)
{
/* log something */
}
}
@@ -166,6 +160,7 @@ public sealed class ListItemViewModel : INotifyPropertyChanged, IDisposable
// this is highly unusual
return;
}
this.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
{
this.PropertyChanged?.Invoke(this, new(propertyName));

View File

@@ -13,10 +13,8 @@ namespace DeveloperCommandPalette;
// cribbed heavily from
//
// https://github.com/microsoft/WindowsAppSDK-Samples/tree/main/Samples/AppLifecycle/Instancing/cs2/cs-winui-packaged/CsWinUiDesktopInstancing
sealed class Program
sealed class Program
{
private static App? app;
// LOAD BEARING
@@ -35,6 +33,7 @@ sealed class Program
app = new App();
});
}
return 0;
}
@@ -53,6 +52,7 @@ sealed class Program
isRedirect = true;
_ = keyInstance.RedirectActivationToAsync(args);
}
return isRedirect;
}
@@ -60,7 +60,7 @@ sealed class Program
{
ExtendedActivationKind kind = args.Kind;
_ = kind;
//app?.
// If we already have a form, display the message now.
// Otherwise, add it to the collection for displaying later.
if (App.Current is App thisApp)

View File

@@ -23,7 +23,7 @@ using WindowsCommandPalette.Builtins;
namespace WindowsCommandPalette.Views;
sealed class ActionsProviderWrapper
internal sealed class ActionsProviderWrapper
{
public bool IsExtension => extensionWrapper != null;
@@ -88,4 +88,9 @@ sealed class ActionsProviderWrapper
}
public override bool Equals(object? obj) => obj is ActionsProviderWrapper wrapper && isValid == wrapper.isValid;
public override int GetHashCode()
{
throw new NotImplementedException();
}
}

View File

@@ -45,7 +45,6 @@
Tapped="ListItem_Tapped"
MinHeight="32"
Height="24"
DoubleTapped="ListViewItem_DoubleTapped"
Visibility="{x:Bind Title, Converter={StaticResource StringNotEmptyToVisibilityConverter}, Mode=OneWay}">
<Grid>
<Grid.ColumnDefinitions>

View File

@@ -39,7 +39,8 @@ public class SectionInfoList : ObservableCollection<ListItemViewModel>
private readonly DispatcherQueue DispatcherQueue = DispatcherQueue.GetForCurrentThread();
public SectionInfoList(ISection? section, IEnumerable<ListItemViewModel> items) : base(items)
public SectionInfoList(ISection? section, IEnumerable<ListItemViewModel> items)
: base(items)
{
Title = section?.Title ?? string.Empty;
if (section != null && section is INotifyCollectionChanged observable)
@@ -47,6 +48,7 @@ public class SectionInfoList : ObservableCollection<ListItemViewModel>
observable.CollectionChanged -= Items_CollectionChanged;
observable.CollectionChanged += Items_CollectionChanged;
}
if (this.DispatcherQueue == null)
{
throw new InvalidOperationException("DispatcherQueue is null");
@@ -55,7 +57,7 @@ public class SectionInfoList : ObservableCollection<ListItemViewModel>
private void Items_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
//DispatcherQueue.TryEnqueue(() => {
// DispatcherQueue.TryEnqueue(() => {
if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems != null)
{
foreach (var i in e.NewItems)
@@ -66,34 +68,39 @@ public class SectionInfoList : ObservableCollection<ListItemViewModel>
{
ListItemViewModel vm = new(li);
this.Add(vm);
}
//if (isDynamic)
//{
// if (isDynamic)
// {
// // Dynamic lists are in charge of their own
// // filtering. They know if this thing was already
// // filtered or not.
// FilteredItems.Add(vm);
//}
// }
}
}
}
else if (e.Action == NotifyCollectionChangedAction.Reset)
{
this.Clear();
//Items.Clear();
//if (isDynamic)
//{
// Items.Clear();
// if (isDynamic)
// {
// FilteredItems.Clear();
//}
// }
}
//});
// });
}
}
public sealed class NoOpAction : InvokableCommand
{
public override ICommandResult Invoke() { return ActionResult.KeepOpen(); }
public override ICommandResult Invoke()
{
return ActionResult.KeepOpen();
}
}
public sealed class ErrorListItem : Microsoft.Windows.CommandPalette.Extensions.Helpers.ListItem
@@ -130,8 +137,8 @@ public sealed class ListPageViewModel : PageViewModel
internal async Task UpdateListItems()
{
// on main thread
var t = new Task<ISection[]>(() => {
var t = new Task<ISection[]>(() =>
{
try
{
return dynamicPage != null ?
@@ -141,9 +148,13 @@ public sealed class ListPageViewModel : PageViewModel
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
return [new ListSection() { Title = "Error", Items = [new ErrorListItem(ex)] }];
return [new ListSection()
{
Title = "Error",
Items = [new ErrorListItem(ex)],
}
];
}
});
t.Start();
var sections = await t;
@@ -154,9 +165,8 @@ public sealed class ListPageViewModel : PageViewModel
// we already have, then rebuilding it. We shouldn't do that. We should
// still use the results from GetItems and put them into the code in
// UpdateFilter to intelligently add/remove as needed.
//Items.Clear();
//FilteredItems.Clear();
// Items.Clear();
// FilteredItems.Clear();
Collection<SectionInfoList> newItems = new();
var size = sections.Length;
@@ -186,12 +196,13 @@ public sealed class ListPageViewModel : PageViewModel
ListHelpers.InPlaceUpdateList(FilteredItems, newItems);
}
internal async Task<Collection<SectionInfoList>> GetFilteredItems(string query) {
internal async Task<Collection<SectionInfoList>> GetFilteredItems(string query)
{
if (query == Query)
{
return FilteredItems;
}
Query = query;
if (isDynamic)
{
@@ -207,14 +218,15 @@ public sealed class ListPageViewModel : PageViewModel
}
//// TODO! Probably bad that this turns list view models into listitems back to NEW view models
//return ListHelpers.FilterList(Items.Select(vm => vm.ListItem), Query).Select(li => new ListItemViewModel(li)).ToList();
try{
// return ListHelpers.FilterList(Items.Select(vm => vm.ListItem), Query).Select(li => new ListItemViewModel(li)).ToList();
try
{
var allFilteredItems = ListHelpers.FilterList(
Items
.SelectMany(section => section)
.Select(vm => vm.ListItem.Unsafe),
Query).Select(li => new ListItemViewModel(li)
);
Query).Select(li => new ListItemViewModel(li));
var newSection = new SectionInfoList(null, allFilteredItems);
return [newSection];
}
@@ -265,7 +277,11 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
{
get
{
if (ItemsList.SelectedItem is not ListItemViewModel li) return false;
if (ItemsList.SelectedItem is not ListItemViewModel li)
{
return false;
}
return li.HasMoreCommands;
}
}
@@ -279,13 +295,17 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
{
base.OnNavigatedTo(e);
ViewModel = (ListPageViewModel?)e.Parameter;
if (ViewModel == null) return;
if (ViewModel == null)
{
return;
}
if (e.NavigationMode == NavigationMode.New) {
ViewModel.InitialRender().ContinueWith( (t) => {
if (e.NavigationMode == NavigationMode.New)
{
ViewModel.InitialRender().ContinueWith((t) =>
{
DispatcherQueue.TryEnqueue(async () => { await UpdateFilter(FilterBox.Text); });
});
}
else
{
@@ -303,8 +323,16 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
private void ListItem_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (sender is not ListViewItem listItem) return;
if (listItem.DataContext is not ListItemViewModel li) return;
if (sender is not ListViewItem listItem)
{
return;
}
if (listItem.DataContext is not ListItemViewModel li)
{
return;
}
if (e.OriginalKey == Windows.System.VirtualKey.Enter)
{
if (li.DefaultAction != null)
@@ -327,39 +355,53 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
private void ListItem_Tapped(object sender, TappedRoutedEventArgs e)
{
if (sender is not ListViewItem listItem) return;
if (listItem.DataContext is not ListItemViewModel li) return;
_ = li;
// For a bit I had double-clicks Invoke and single just select, but that crashes?
//ItemsList.SelectedItem = listItem;
if (sender is not ListViewItem listItem)
{
return;
}
if (listItem.DataContext is not ListItemViewModel li)
{
return;
}
_ = li;
// For a bit I had double-clicks Invoke and single just select, but that crashes?
// ItemsList.SelectedItem = listItem;
if (li.DefaultAction != null)
{
DoAction(new(li.DefaultAction));
}
}
private void ListViewItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
//if (sender is not ListViewItem listItem) return;
//if (listItem.DataContext is not ListItemViewModel li) return;
//if (li.DefaultAction != null)
//{
// DoAction(new(li.DefaultAction));
//}
}
private void ItemsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is not ListView lv) return;
if (lv.SelectedItem is not ListItemViewModel li) return;
if (sender is not ListView lv)
{
return;
}
if (lv.SelectedItem is not ListItemViewModel li)
{
return;
}
SelectedItem = li;
}
private void ActionListViewItem_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (sender is not ListViewItem listItem) return;
if (listItem.DataContext is not ContextItemViewModel vm) return;
if (sender is not ListViewItem listItem)
{
return;
}
if (listItem.DataContext is not ContextItemViewModel vm)
{
return;
}
if (e.Key == Windows.System.VirtualKey.Enter || e.Key == Windows.System.VirtualKey.Space)
{
DoAction(new(vm.Command));
@@ -369,8 +411,16 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
private void ActionListViewItem_Tapped(object sender, TappedRoutedEventArgs e)
{
if (sender is not ListViewItem listItem) return;
if (listItem.DataContext is not ContextItemViewModel vm) return;
if (sender is not ListViewItem listItem)
{
return;
}
if (listItem.DataContext is not ContextItemViewModel vm)
{
return;
}
DoAction(new(vm.Command));
e.Handled = true;
}
@@ -386,7 +436,10 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
private void FilterBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Handled) return;
if (e.Handled)
{
return;
}
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Control).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down);
if (e.Key == Windows.System.VirtualKey.Up || e.Key == Windows.System.VirtualKey.Down)
@@ -397,6 +450,7 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
ItemsList.SelectedIndex = newIndex;
ItemsList.ScrollIntoView(ItemsList.SelectedItem);
}
e.Handled = true;
}
else if (e.Key == Windows.System.VirtualKey.Enter /* && ItemsList.SelectedItem != null */)
@@ -407,6 +461,7 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
{
DoAction(new(li.DefaultAction));
}
e.Handled = true;
}
}
@@ -420,10 +475,10 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
{
ViewModel?.GoBack();
}
e.Handled = true;
}
// ctrl+k
else if (ctrlPressed && e.Key == Windows.System.VirtualKey.K)
else if (ctrlPressed && e.Key == Windows.System.VirtualKey.K) // ctrl+k
{
// Open the more actions flyout and focus the first item
if (ActionsDropdown.Items.Count > 0)
@@ -441,14 +496,21 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
private void FilterBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (ViewModel == null) return;
if (ViewModel == null)
{
return;
}
// on the UI thread
_ = UpdateFilter(FilterBox.Text);
}
private async Task UpdateFilter(string text)
{
if (ViewModel == null) return;
if (ViewModel == null)
{
return;
}
// ViewModel.Query = text;
@@ -456,9 +518,12 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
// into us initially. We handle the filtering of these ones. Commands
// from async querying happens later.
var newMatches = await ViewModel.GetFilteredItems(text);
// this.ItemsCVS.Source = ViewModel.FilteredItems;
// Returns back on the UI thread
ListHelpers.InPlaceUpdateList(ViewModel.FilteredItems, newMatches);
/*
// for (var i = 0; i < ViewModel.FilteredItems.Count && i < newMatches.Count; i++)
// {
// for (var j = i; j < ViewModel.FilteredItems.Count; j++)
@@ -490,6 +555,7 @@ public sealed partial class ListPage : Page, System.ComponentModel.INotifyProper
// {
// ViewModel.FilteredItems.Add(newMatches[ViewModel.FilteredItems.Count]);
// }
*/
// set the selected index to the first item in the list
if (ItemsList.Items.Count > 0)

View File

@@ -55,7 +55,6 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
@@ -66,7 +65,6 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
return;
}
ViewModel.InitialRender(this).ContinueWith((t) => {
DispatcherQueue.TryEnqueue(() =>
{
@@ -76,12 +74,13 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
mdTextBox.Text = ViewModel.MarkdownContent[0];
TitleBlock.Text = ViewModel.Title;
}
// if (ViewModel.PageCommand != null)
// {
// if (ViewModel.PageCommand != null)
// {
// ActionsDropdown.ItemsSource = ViewModel.PageCommand.Commands;
// this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MoreCommandsAvailable)));
// // this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemDefaultAction)));
// }
// }
});
});
}
@@ -91,7 +90,9 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
ViewModel?.DoAction(actionViewModel);
}
private void Page_Loaded(object sender, RoutedEventArgs e) {}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
}
private void MarkdownScrollViewer_KeyDown(object sender, KeyRoutedEventArgs e)
{
@@ -118,11 +119,12 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
{
FlyoutShowOptions options = new FlyoutShowOptions
{
ShowMode = FlyoutShowMode.Standard
ShowMode = FlyoutShowMode.Standard,
};
MoreCommandsButton.Flyout.ShowAt(MoreCommandsButton, options);
//ActionsDropdown.SelectedIndex = 0;
//ActionsDropdown.Focus(FocusState.Programmatic);
// ActionsDropdown.SelectedIndex = 0;
// ActionsDropdown.Focus(FocusState.Programmatic);
}
#pragma warning disable CA1822 // Mark members as static
@@ -130,8 +132,16 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
private void ActionListViewItem_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (sender is not ListViewItem listItem) return;
if (listItem.DataContext is not ContextItemViewModel vm) return;
if (sender is not ListViewItem listItem)
{
return;
}
if (listItem.DataContext is not ContextItemViewModel vm)
{
return;
}
if (e.Key == Windows.System.VirtualKey.Enter || e.Key == Windows.System.VirtualKey.Space)
{
DoAction(new(vm.Command));
@@ -141,15 +151,27 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
private void ActionListViewItem_Tapped(object sender, TappedRoutedEventArgs e)
{
if (sender is not ListViewItem listItem) return;
if (listItem.DataContext is not ContextItemViewModel vm) return;
if (sender is not ListViewItem listItem)
{
return;
}
if (listItem.DataContext is not ContextItemViewModel vm)
{
return;
}
DoAction(new(vm.Command));
e.Handled = true;
}
private void RootGrid_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Handled) return;
if (e.Handled)
{
return;
}
var ctrlPressed = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Control).HasFlag(Windows.UI.Core.CoreVirtualKeyStates.Down);
if (ctrlPressed && e.Key == Windows.System.VirtualKey.K)
@@ -159,7 +181,7 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
{
FlyoutShowOptions options = new FlyoutShowOptions
{
ShowMode = FlyoutShowMode.Standard
ShowMode = FlyoutShowMode.Standard,
};
MoreCommandsButton.Flyout.ShowAt(MoreCommandsButton, options);
ActionsDropdown.SelectedIndex = 0;
@@ -167,5 +189,4 @@ public sealed partial class MarkdownPage : Page, System.ComponentModel.INotifyPr
}
}
}
}