Skip to content

Commit

Permalink
feat: 🚧 storage
Browse files Browse the repository at this point in the history
  • Loading branch information
Daydreamer-riri committed Mar 15, 2024
1 parent 7b9a487 commit 211d247
Show file tree
Hide file tree
Showing 7 changed files with 541 additions and 7 deletions.
236 changes: 229 additions & 7 deletions Community.PowerToys.Run.Plugin.WebSearchShortcut/Main.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,235 @@
namespace UtilityLibraries;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Community.PowerToys.Run.Plugin.WebSearchShortcut.Models;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using Wox.Infrastructure.Storage;
using Wox.Plugin;
using Wox.Plugin.Logger;

public static class WebSearchShortcut
namespace Community.PowerToys.Run.Plugin.WebSearchShortcut
{
public static bool StartsWithUpper(this string? str)
/// <summary>
/// Main class of this plugin that implement all used interfaces.
/// </summary>
public class Main : IPlugin, ISettingProvider, IDisposable
{
if (string.IsNullOrWhiteSpace(str))
return false;
/// <summary>
/// Initializes a new instance of the <see cref="Main"/> class.
/// </summary>
public Main()
{
Storage = new PluginJsonStorage<WebSearchShortcutSettings>();
Settings = Storage.Load();
Settings.StorageDirectoryPath = Storage.DirectoryPath;
WebSearchShortcutStorage = new WebSearchShortcutStorage(Settings);
}

char ch = str[0];
return char.IsUpper(ch);
internal Main(WebSearchShortcutSettings settings, IWebSearchShortcutStorage webSearchShortcutStorage)
{
Storage = new PluginJsonStorage<WebSearchShortcutSettings>();
Settings = settings;
WebSearchShortcutStorage = webSearchShortcutStorage;
}
/// <summary>
/// ID of the plugin.
/// </summary>
public static string PluginID => "B5E595872B8068104D5AD6BBE39A6664";

/// <summary>
/// Name of the plugin.
/// </summary>
public string Name => "WebSearchShortcut";

/// <summary>
/// Description of the plugin.
/// </summary>
public string Description => "Count words and characters in text";

/// <summary>
/// Additional options for the plugin.
/// </summary>
public IEnumerable<PluginAdditionalOption> AdditionalOptions => Settings.GetAdditionalOptions();

private PluginInitContext? Context { get; set; }

private string? IconPath { get; set; }

private bool Disposed { get; set; }

private PluginJsonStorage<WebSearchShortcutSettings> Storage { get; }

private WebSearchShortcutSettings Settings { get; }

private IWebSearchShortcutStorage WebSearchShortcutStorage { get; }

/// <summary>
/// Return a filtered list, based on the given query.
/// </summary>
/// <param name="query">The query to filter the list.</param>
/// <returns>A filtered list, can be empty when nothing was found.</returns>
public List<Result> Query(Query query)
{
if (query?.Search is null)
{
return [];
}

var args = query.Search;

if (string.IsNullOrEmpty(args))
{
return WebSearchShortcutStorage.GetRecords().Select(GetResultForGetRecord).ToList();
}

return WebSearchShortcutStorage.GetRecords(args).Select(GetResultForGetRecord).ToList() ?? [];


Result GetResultForGetRecord(Item record) => new()
{
QueryTextDisplay = args,
IcoPath = IconPath,
Title = record.Name,
SubTitle = record.Url,
// ToolTipData = new ToolTipData("Get", $"Key: {record.Key}\nValue: {record.Value}\nCreated: {record.Created}\nUpdated: {record.Updated}"),
ContextData = record,
};
}

/// <summary>
/// Initialize the plugin with the given <see cref="PluginInitContext"/>.
/// </summary>
/// <param name="context">The <see cref="PluginInitContext"/> for this plugin.</param>
public void Init(PluginInitContext context)
{
Log.Info("Init", GetType());

Context = context ?? throw new ArgumentNullException(nameof(context));
Context.API.ThemeChanged += OnThemeChanged;
UpdateIconPath(Context.API.GetCurrentTheme());
}

// /// <summary>
// /// Return a list context menu entries for a given <see cref="Result"/> (shown at the right side of the result).
// /// </summary>
// /// <param name="selectedResult">The <see cref="Result"/> for the list with context menu entries.</param>
// /// <returns>A list context menu entries.</returns>
// public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
// {
// Log.Info("LoadContextMenus", GetType());

// if (selectedResult?.ContextData is (int words, TimeSpan transcription))
// {
// return
// [
// new ContextMenuResult
// {
// PluginName = Name,
// Title = "Copy (Enter)",
// FontFamily = "Segoe Fluent Icons,Segoe MDL2 Assets",
// Glyph = "\xE8C8", // Copy
// AcceleratorKey = Key.Enter,
// Action = _ => CopyToClipboard(words.ToString()),
// },
// new ContextMenuResult
// {
// PluginName = Name,
// Title = "Copy time (Ctrl+Enter)",
// FontFamily = "Segoe Fluent Icons,Segoe MDL2 Assets",
// Glyph = "\xE916", // Stopwatch
// AcceleratorKey = Key.Enter,
// AcceleratorModifiers = ModifierKeys.Control,
// Action = _ => CopyToClipboard(transcription.ToString()),
// },
// ];
// }

// if (selectedResult?.ContextData is int characters)
// {
// return
// [
// new ContextMenuResult
// {
// PluginName = Name,
// Title = "Copy (Enter)",
// FontFamily = "Segoe Fluent Icons,Segoe MDL2 Assets",
// Glyph = "\xE8C8", // Copy
// AcceleratorKey = Key.Enter,
// Action = _ => CopyToClipboard(characters.ToString()),
// },
// ];
// }

// return [];
// }

/// <summary>
/// Creates setting panel.
/// </summary>
/// <returns>The control.</returns>
/// <exception cref="NotImplementedException">method is not implemented.</exception>
public Control CreateSettingPanel() => throw new NotImplementedException();

/// <summary>
/// Updates settings.
/// </summary>
/// <param name="settings">The plugin settings.</param>
public void UpdateSettings(PowerLauncherPluginSettings settings)
{
Log.Info("UpdateSettings", GetType());

// CountSpaces = settings.AdditionalOptions.SingleOrDefault(x => x.Key == nameof(CountSpaces))?.Value ?? false;
}

public void ReloadData()
{
WebSearchShortcutStorage.Load();
}

/// <inheritdoc/>
public void Dispose()
{
Log.Info("Dispose", GetType());

Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Wrapper method for <see cref="Dispose()"/> that dispose additional objects and events form the plugin itself.
/// </summary>
/// <param name="disposing">Indicate that the plugin is disposed.</param>
protected virtual void Dispose(bool disposing)
{
if (Disposed || !disposing)
{
return;
}

if (Context?.API != null)
{
Context.API.ThemeChanged -= OnThemeChanged;
}

Disposed = true;
}

private void UpdateIconPath(Theme theme) => IconPath = theme == Theme.Light || theme == Theme.HighContrastWhite ? Context?.CurrentPluginMetadata.IcoPathLight : Context?.CurrentPluginMetadata.IcoPathDark;

private void OnThemeChanged(Theme currentTheme, Theme newTheme) => UpdateIconPath(newTheme);

private static bool CopyToClipboard(string? value)
{
if (value != null)
{
Clipboard.SetText(value);
}

return true;
}
}
}
34 changes: 34 additions & 0 deletions Community.PowerToys.Run.Plugin.WebSearchShortcut/Models/Item.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;

namespace Community.PowerToys.Run.Plugin.WebSearchShortcut.Models
{
/// <summary>
/// Key/value record.
/// </summary>
public class Item
{
/// <summary>
/// The key.
/// </summary>
public string KeyWord { get; set; } = string.Empty;

/// <summary>
/// The value.
/// </summary>
public string Name { get; set; } = string.Empty;

public string Url { get; set; } = string.Empty;

public string? IconPath { get; set; }

/// <summary>
/// When the record was created.
/// </summary>
public DateTime Created { get; set; }

/// <summary>
/// When the record was updated.
/// </summary>
public DateTime? Updated { get; set; }
}
}
53 changes: 53 additions & 0 deletions Community.PowerToys.Run.Plugin.WebSearchShortcut/Query.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Linq;
using Community.PowerToys.Run.Plugin.WebSearchShortcut.Models;

namespace Community.PowerToys.Run.Plugin.WebSearchShortcut.Helpers
{
public interface IQuery
{
IEnumerable<Item> GetAll();

IEnumerable<Item> Search(string query);
}

public class Query: IQuery {
private readonly IWebSearchShortcutStorage _webSearchShortcutStorage;
public Query(IWebSearchShortcutStorage webSearchShortcutStorage)
{
_webSearchShortcutStorage = webSearchShortcutStorage;
}
public IEnumerable<Item> Search(string query)
{
var path = query.Replace('\\', '/').Split('/');
return _webSearchShortcutStorage.GetRecords(query);

// if (_profileManager.FavoriteProviders.Count == 1)
// {
// return Search(_profileManager.FavoriteProviders[0].Root, path, 0);
// }
// else
// {
// var results = new List<Item>();

// foreach (var root in _webSearchShortcutStorage.GetRecords())
// {
// results.AddRange(Search(root, path, 0));
// }

// // Flatten folders with same path for each profiles
// return results.DistinctBy(f => new { f.Path, f.Type, f.Profile });
// }
}

public IEnumerable<Item> GetAll()
{
return _webSearchShortcutStorage.GetRecords();
}

// private IEnumerable<Item> Search(Item node, string query)
// {
// return [.. _webSearchShortcutStorage.GetRecords(query)];
// }
}
}
60 changes: 60 additions & 0 deletions Community.PowerToys.Run.Plugin.WebSearchShortcut/Settings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.PowerToys.Settings.UI.Library;

namespace Community.PowerToys.Run.Plugin.WebSearchShortcut
{
/// <summary>
/// Plugin settings.
/// </summary>
public class WebSearchShortcutSettings
{
private string _storageFileName = WebSearchShortcutStorage.DefaultFileName;

/// <summary>
/// File store.
/// </summary>
public string StorageFileName
{
get => _storageFileName;
set => _storageFileName = IsValidFileName(value) ? value : WebSearchShortcutStorage.DefaultFileName;
}

internal string StorageDirectoryPath { get; set; } = null!;

internal IEnumerable<PluginAdditionalOption> GetAdditionalOptions()
{
return
[
new()
{
Key = nameof(StorageFileName),
DisplayLabel = "Storage File Name",
DisplayDescription = StorageDirectoryPath,
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Textbox,
TextValue = StorageFileName,
},
];
}

internal void SetAdditionalOptions(IEnumerable<PluginAdditionalOption> additionalOptions)
{
ArgumentNullException.ThrowIfNull(additionalOptions);

var options = additionalOptions.ToList();
StorageFileName = options.Find(x => x.Key == nameof(StorageFileName))?.TextValue ?? WebSearchShortcutStorage.DefaultFileName;
}

private static bool IsValidFileName(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return false;
}

return value.IndexOfAny(Path.GetInvalidFileNameChars()) < 0;
}
}
}
Loading

0 comments on commit 211d247

Please sign in to comment.