Merge pull request #32 from zadjii-msft/dev/crutkas/moreCleanup

Bookmarks so it can serialize / deserialize via objects
This commit is contained in:
Clint Rutkas
2024-09-04 15:00:59 -07:00
committed by GitHub
11 changed files with 144 additions and 156 deletions

View File

@@ -2,16 +2,16 @@
// 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.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using Microsoft.Bot.AdaptiveExpressions.Core;
using Microsoft.Windows.CommandPalette.Extensions;
using Microsoft.Windows.CommandPalette.Extensions.Helpers;
using Windows.Foundation;
using Windows.System;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Run.Bookmarks;
@@ -21,8 +21,8 @@ internal sealed class OpenInTerminalAction : InvokableCommand
public OpenInTerminalAction(string folder)
{
this.Name = "Open in Terminal";
this._folder = folder;
Name = "Open in Terminal";
_folder = folder;
}
public override ICommandResult Invoke()
@@ -34,7 +34,7 @@ internal sealed class OpenInTerminalAction : InvokableCommand
{
FileName = "wt.exe",
Arguments = $"-d \"{_folder}\"",
UseShellExecute = true
UseShellExecute = true,
};
System.Diagnostics.Process.Start(startInfo);
}
@@ -47,11 +47,16 @@ internal sealed class OpenInTerminalAction : InvokableCommand
}
}
internal sealed class BookmarkData
public class BookmarkData
{
internal string name = string.Empty;
internal string bookmark = string.Empty;
internal string type = string.Empty;
public string Name = string.Empty;
public string Bookmark = string.Empty;
public string Type = string.Empty;
}
public sealed class Bookmarks
{
public List<BookmarkData> Data { get; set; } = [];
}
[JsonSourceGenerationOptions(WriteIndented = true)]
@@ -149,61 +154,48 @@ internal sealed class AddBookmarkForm : Form
bookmarkType = "web";
}
var formData = new BookmarkData()
{
Name = formName.ToString(),
Bookmark = formBookmark.ToString(),
Type = bookmarkType,
};
// Construct a new json blob with the name and url
var json = string.Empty;
var jsonPath = BookmarksActionProvider.StateJsonPath();
Bookmarks data;
// if the file exists, load it and append the new item
if (File.Exists(BookmarksActionProvider.StateJsonPath()))
if (File.Exists(jsonPath))
{
var state = File.ReadAllText(BookmarksActionProvider.StateJsonPath());
var jsonState = JsonNode.Parse(state);
var items = jsonState?["items"]?.AsArray();
var jsonStringReading = File.ReadAllText(jsonPath);
if (items != null)
{
// var items = jsonState["items"];
var newItem = new JsonObject();
newItem["name"] = formName;
newItem["bookmark"] = formBookmark;
var formData = new BookmarkData()
{
name = formName.ToString(),
bookmark = formBookmark.ToString(),
type = bookmarkType,
};
items.Add(JsonSerializer.SerializeToNode(formData, typeof(BookmarkData), SourceGenerationContext.Default));
json = jsonState?.ToString();
}
data = JsonSerializer.Deserialize<Bookmarks>(jsonStringReading);
}
else
{
json = $$"""
{
"items": [
{
"name": "{{formName}}",
"type": "{{bookmarkType}}",
"bookmark": "{{formBookmark}}",
"hasPlaceholder":"{{hasPlaceholder}}"
}
]
}
""";
data = new Bookmarks();
}
File.WriteAllText(BookmarksActionProvider.StateJsonPath(), json);
data.Data.Add(formData);
var options = new JsonSerializerOptions()
{
IncludeFields = true,
};
var jsonString = JsonSerializer.Serialize<Bookmarks>(data, options);
File.WriteAllText(BookmarksActionProvider.StateJsonPath(), jsonString);
AddedAction?.Invoke(this, null);
return ActionResult.GoHome();
}
}
internal sealed class AddBookmarkPage : Microsoft.Windows.CommandPalette.Extensions.Helpers.FormPage
internal sealed class AddBookmarkPage : FormPage
{
private readonly AddBookmarkForm _addBookmark = new();
internal event TypedEventHandler<object, object?>? AddedAction {
internal event TypedEventHandler<object, object?>? AddedAction
{
add => _addBookmark.AddedAction += value;
remove => _addBookmark.AddedAction -= value;
}
@@ -217,23 +209,25 @@ internal sealed class AddBookmarkPage : Microsoft.Windows.CommandPalette.Extensi
}
}
internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.Extensions.Helpers.Form
internal sealed class BookmarkPlaceholderForm : Microsoft.Windows.CommandPalette.Extensions.Helpers.Form
{
private List<string> placeholderNames { get; init; }
private readonly List<string> _placeholderNames;
private readonly string _Bookmark = string.Empty;
private readonly string _bookmark = string.Empty;
// TODO pass in an array of placeholders
public BookmarkPlaceholderForm(string name, string url, string type) {
_Bookmark = url;
public BookmarkPlaceholderForm(string name, string url, string type)
{
_bookmark = url;
Regex r = new Regex(Regex.Escape("{") + "(.*?)" + Regex.Escape("}"));
MatchCollection matches = r.Matches(url);
placeholderNames = matches.Select(m => m.Groups[1].Value).ToList();
_placeholderNames = matches.Select(m => m.Groups[1].Value).ToList();
}
public override string TemplateJson()
{
var inputs = placeholderNames.Select(p => {
var inputs = _placeholderNames.Select(p =>
{
return $$"""
{
"type": "Input.Text",
@@ -276,7 +270,7 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
public override ActionResult SubmitForm(string payload)
{
var target = _Bookmark;
var target = _bookmark;
// parse the submitted JSON and then open the link
var formInput = JsonNode.Parse(payload);
@@ -314,7 +308,7 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
}
}
internal sealed class BookmarkPlaceholderPage : Microsoft.Windows.CommandPalette.Extensions.Helpers.FormPage
internal sealed class BookmarkPlaceholderPage : FormPage
{
private readonly IForm _bookmarkPlaceholder;
@@ -330,11 +324,11 @@ internal sealed class BookmarkPlaceholderPage : Microsoft.Windows.CommandPalette
public class UrlAction : InvokableCommand
{
private bool _containsPlaceholder => _url.Contains('{') && _url.Contains('}');
private bool IsContainsPlaceholder => _url.Contains('{') && _url.Contains('}');
public string Type { get; }
public string Url { get; }
public string Url { get; }
private readonly string _url;
@@ -428,12 +422,12 @@ public class BookmarksActionProvider : ICommandProvider
public BookmarksActionProvider()
{
_addNewCommand.AddedAction += _addNewCommand_AddedAction;
_addNewCommand.AddedAction += AddNewCommand_AddedAction;
}
private void _addNewCommand_AddedAction(object sender, object? args)
private void AddNewCommand_AddedAction(object sender, object? args)
{
_addNewCommand.AddedAction += _addNewCommand_AddedAction;
_addNewCommand.AddedAction += AddNewCommand_AddedAction;
_commands.Clear();
}
@@ -447,42 +441,37 @@ public class BookmarksActionProvider : ICommandProvider
collected.Add(_addNewCommand);
try
{
// Open state.json from the disk and read it
var state = File.ReadAllText(BookmarksActionProvider.StateJsonPath());
// Parse the JSON
var json = JsonNode.Parse(state);
var jsonObject = json?.AsObject();
if (jsonObject == null)
var jsonFile = StateJsonPath();
if (File.Exists(jsonFile))
{
return;
}
if (!jsonObject.ContainsKey("items"))
{
return;
}
var itemsJson = jsonObject["items"]?.AsArray();
if (itemsJson == null)
{
return;
}
foreach (var item in itemsJson)
{
var nameToken = item?["name"];
var urlToken = item?["bookmark"];
var typeToken = item?["type"];
if (nameToken == null || urlToken == null || typeToken == null)
// Open state.json from the disk and read it
var jsonString = File.ReadAllText(jsonFile);
var options = new JsonSerializerOptions()
{
continue;
}
IncludeFields = true,
};
var data = JsonSerializer.Deserialize<Bookmarks>(jsonString, options);
var name = nameToken.ToString();
var url = urlToken.ToString();
var type = typeToken.ToString();
collected.Add((url.Contains('{') && url.Contains('}')) ? new BookmarkPlaceholderPage(name, url, type) : new UrlAction(name, url, type));
if (data != null)
{
var items = data?.Data;
foreach (var item in items)
{
var nameToken = item.Name;
var urlToken = item.Bookmark;
var typeToken = item.Type;
if (nameToken == null || urlToken == null || typeToken == null)
{
continue;
}
var name = nameToken.ToString();
var url = urlToken.ToString();
var type = typeToken.ToString();
collected.Add((url.Contains('{') && url.Contains('}')) ? new BookmarkPlaceholderPage(name, url, type) : new UrlAction(name, url, type));
}
}
}
}
catch (Exception ex)
@@ -515,11 +504,11 @@ public class BookmarksActionProvider : ICommandProvider
}
// listItem.Subtitle = "Bookmark";
if (action is AddBookmarkPage) { }
else
if (action is not AddBookmarkPage)
{
listItem.Tags = [
new Tag() {
new Tag()
{
Text = "Bookmark",
// Icon = new("🔗"),

View File

@@ -27,7 +27,7 @@ internal sealed class AppAction : InvokableCommand
{
try
{
appManager.ActivateApplication(amuid, /*queryArguments*/ "", noFlags, out var unusedPid);
appManager.ActivateApplication(amuid, /*queryArguments*/ string.Empty, noFlags, out var unusedPid);
}
catch (System.Exception)
{

View File

@@ -6,12 +6,17 @@ namespace WindowsCommandPalette.BuiltinCommands.AllApps;
internal sealed class AppItem
{
public string Name { get; set; } = "";
public string Subtitle { get; set; } = "";
public string IcoPath { get; set; } = "";
public string ExePath { get; set; } = "";
public string DirPath { get; set; } = "";
public string UserModelId { get; set; } = "";
public string Name { get; set; } = string.Empty;
public string Subtitle { get; set; } = string.Empty;
public string IcoPath { get; set; } = string.Empty;
public string ExePath { get; set; } = string.Empty;
public string DirPath { get; set; } = string.Empty;
public string UserModelId { get; set; } = string.Empty;
public AppItem()
{

View File

@@ -8,10 +8,12 @@ namespace WindowsCommandPalette.BuiltinCommands.AllApps;
internal sealed class AppListItem : ListItem
{
private readonly AppItem app;
public AppListItem(AppItem app) : base(new AppAction(app))
private readonly AppItem _app;
public AppListItem(AppItem app)
: base(new AppAction(app))
{
this.app = app;
this._app = app;
this.Title = app.Name;
this.Subtitle = app.Subtitle;
this.Details = new Details() { Title = this.Title, HeroImage = this.Command.Icon, Body = "### App" };
@@ -21,7 +23,7 @@ internal sealed class AppListItem : ListItem
{
// Win32 exe or other non UWP app
this._MoreCommands = [
new CommandContextItem(new OpenPathAction(app.DirPath){ Name = "Open location", Icon=new("\ue838") })
new CommandContextItem(new OpenPathAction(app.DirPath) { Name = "Open location", Icon=new("\ue838") })
];
}
else

View File

@@ -25,23 +25,9 @@ public class PackageManagerWrapper : IPackageManager
{
var pkgs = _packageManager.FindPackagesForUser(user.Value);
return pkgs.Select(TryGetWrapperFromPackage).Where(package => package != null);
return pkgs.Select(PackageWrapper.GetWrapperFromPackage).Where(package => package != null);
}
return Enumerable.Empty<IPackage>();
}
private static PackageWrapper TryGetWrapperFromPackage(Package package)
{
try
{
return PackageWrapper.GetWrapperFromPackage(package);
}
catch (Exception )
{
// Log.Error(e.Message, typeof(PackageManagerWrapper));
}
return null;
}
}

View File

@@ -632,7 +632,7 @@ public class Win32Program // : IProgram
public static List<Win32Program> DeduplicatePrograms(IEnumerable<Win32Program> programs)
=> new HashSet<Win32Program>(programs, Win32ProgramEqualityComparer.Default).ToList();
private static Win32Program? GetProgramFromPath(string path)
private static Win32Program GetProgramFromPath(string path)
{
var extension = Extension(path);
if (ExecutableApplicationExtensions.Contains(extension))
@@ -649,7 +649,7 @@ public class Win32Program // : IProgram
case InternetShortcutExtension:
return InternetShortcutProgram(path);
default:
return null;
return new Win32Program();
}
}

View File

@@ -14,7 +14,8 @@ public sealed class MainListItem : ListItem
public IListItem Item => _listItem;
internal MainListItem(IListItem listItem) : base(listItem.Command)
internal MainListItem(IListItem listItem)
: base(listItem.Command)
{
_listItem = listItem;

View File

@@ -114,7 +114,6 @@ public sealed partial class MainWindow : Window
hotKeyPrc = HotKeyPrc;
var hotKeyPrcPointer = Marshal.GetFunctionPointerForDelegate(hotKeyPrc);
origPrc = Marshal.GetDelegateForFunctionPointer<WNDPROC>((IntPtr)Windows.Win32.PInvoke.SetWindowLongPtr(hwnd, WINDOW_LONG_PTR_INDEX.GWL_WNDPROC, hotKeyPrcPointer));
}
private void PositionCentered()
@@ -123,10 +122,11 @@ public sealed partial class MainWindow : Window
DisplayArea displayArea = DisplayArea.GetFromWindowId(m_AppWindow.Id, DisplayAreaFallback.Nearest);
if (displayArea is not null)
{
var CenteredPosition = AppWindow.Position;
CenteredPosition.X = ((displayArea.WorkArea.Width - AppWindow.Size.Width) / 2);
CenteredPosition.Y = ((displayArea.WorkArea.Height - AppWindow.Size.Height) / 2);
AppWindow.Move(CenteredPosition);
var centeredPosition = AppWindow.Position;
centeredPosition.X = (displayArea.WorkArea.Width - AppWindow.Size.Width) / 2;
centeredPosition.Y = (displayArea.WorkArea.Height - AppWindow.Size.Height) / 2;
AppWindow.Move(centeredPosition);
}
}
@@ -146,14 +146,14 @@ public sealed partial class MainWindow : Window
if (key != null)
{
var o = key.GetValue("TaskbarGlomLevel");
if (o != null && o is Int32 i)
if (o != null && o is int i)
{
onLeft = i > 0;
}
if (!onLeft)
{
o = key.GetValue("TaskbarAl");
if (o != null && o is Int32 j)
if (o != null && o is int j)
{
onLeft = j == 0;
}
@@ -162,24 +162,25 @@ public sealed partial class MainWindow : Window
}
catch (Exception)
{
//react appropriately
// react appropriately
}
Microsoft.UI.Windowing.DisplayArea displayArea = Microsoft.UI.Windowing.DisplayArea.GetFromWindowId(m_AppWindow.Id, Microsoft.UI.Windowing.DisplayAreaFallback.Nearest);
if (displayArea is not null)
{
var CenteredPosition = m_AppWindow.Position;
var centeredPosition = m_AppWindow.Position;
if (onLeft)
{
CenteredPosition.X = 16;
CenteredPosition.Y = ((displayArea.WorkArea.Height - m_AppWindow.Size.Height) - 16);
centeredPosition.X = 16;
centeredPosition.Y = displayArea.WorkArea.Height - m_AppWindow.Size.Height - 16;
}
else
{
CenteredPosition.X = ((displayArea.WorkArea.Width - m_AppWindow.Size.Width) / 2);
CenteredPosition.Y = ((displayArea.WorkArea.Height - m_AppWindow.Size.Height) - 16);
centeredPosition.X = (displayArea.WorkArea.Width - m_AppWindow.Size.Width) / 2;
centeredPosition.Y = displayArea.WorkArea.Height - m_AppWindow.Size.Height - 16;
}
m_AppWindow.Move(CenteredPosition);
m_AppWindow.Move(centeredPosition);
}
}

View File

@@ -44,21 +44,21 @@ public sealed class FormViewModel : System.ComponentModel.INotifyPropertyChanged
internal void InitialRender()
{
//var t = new Task<bool>(() => {
this.TemplateJson = this.form.TemplateJson();
try
{
this.DataJson = this.form.DataJson();
}
catch (Exception)
{
this.DataJson = "{}";
}
//return true;
//});
//t.Start();
//await t;
// var t = new Task<bool>(() => {
this.TemplateJson = this.form.TemplateJson();
try
{
this.DataJson = this.form.DataJson();
}
catch (Exception)
{
this.DataJson = "{}";
}
// return true;
// });
// t.Start();
// await t;
AdaptiveCardTemplate template = new(TemplateJson);
var cardJson = template.Expand(DataJson);
this.card = AdaptiveCard.FromJsonString(cardJson);
@@ -103,7 +103,8 @@ public sealed class FormPageViewModel : PageViewModel
internal ObservableCollection<FormViewModel> Forms = new();
public FormPageViewModel(IFormPage page) : base(page)
public FormPageViewModel(IFormPage page)
: base(page)
{
}

View File

@@ -105,7 +105,9 @@ public sealed class NoOpAction : InvokableCommand
public sealed class ErrorListItem : Microsoft.Windows.CommandPalette.Extensions.Helpers.ListItem
{
public ErrorListItem(Exception ex) : base(new NoOpAction()) {
public ErrorListItem(Exception ex)
: base(new NoOpAction())
{
this.Title = "Error in extension:";
this.Subtitle = ex.Message;
}

View File

@@ -28,7 +28,8 @@ public sealed class MarkdownPageViewModel : PageViewModel
internal IList<ContextItemViewModel> ContextActions => contextActions.Select(a => new ContextItemViewModel(a)).ToList();
public MarkdownPageViewModel(IMarkdownPage page) : base(page)
public MarkdownPageViewModel(IMarkdownPage page)
: base(page)
{
}