195 lines
6.1 KiB
C#
195 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Threading;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
public class FavoriteHandler : IActionHandler
|
|
{
|
|
private class FavEntry
|
|
{
|
|
[JsonPropertyName("name")]
|
|
public string Name { get; set; } = "";
|
|
|
|
[JsonPropertyName("path")]
|
|
public string Path { get; set; } = "";
|
|
}
|
|
|
|
private static readonly string FavFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "favorites.json");
|
|
|
|
private static readonly JsonSerializerOptions JsonOpts = new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true,
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
private List<FavEntry> _cache = new List<FavEntry>();
|
|
|
|
private bool _loaded;
|
|
|
|
public string? Prefix => "fav";
|
|
|
|
public PluginMetadata Metadata => new PluginMetadata("Favorite", "즐겨찾기 관리 — fav", "1.0", "AX");
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
EnsureLoaded();
|
|
string q = query.Trim();
|
|
if (q.StartsWith("add ", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string text = q;
|
|
string text2 = text.Substring(4, text.Length - 4).Trim();
|
|
int num = text2.IndexOf(' ');
|
|
if (num > 0)
|
|
{
|
|
string text3 = text2.Substring(0, num).Trim();
|
|
text = text2;
|
|
int num2 = num + 1;
|
|
string text4 = text.Substring(num2, text.Length - num2).Trim();
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("즐겨찾기 추가: " + text3, "경로: " + text4 + " · Enter로 추가", null, ValueTuple.Create("__ADD__", text3, text4), null, "\ue74e")));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("사용법: fav add [이름] [경로]", "예: fav add 보고서 C:\\work\\report.xlsx", null, null, null, "\ue946")));
|
|
}
|
|
if (q.StartsWith("del ", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string text = q;
|
|
string name = text.Substring(4, text.Length - 4).Trim();
|
|
FavEntry favEntry = _cache.FirstOrDefault((FavEntry b) => b.Name.Contains(name, StringComparison.OrdinalIgnoreCase));
|
|
if (favEntry != null)
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("즐겨찾기 삭제: " + favEntry.Name, "경로: " + favEntry.Path + " · Enter로 삭제", null, ValueTuple.Create("__DEL__", favEntry.Name), null, "\ue74d")));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("'" + name + "'에 해당하는 즐겨찾기 없음", "fav으로 전체 목록 확인", null, null, null, "\ue7ba")));
|
|
}
|
|
List<FavEntry> source = (string.IsNullOrWhiteSpace(q) ? _cache : _cache.Where((FavEntry b) => b.Name.Contains(q, StringComparison.OrdinalIgnoreCase) || b.Path.Contains(q, StringComparison.OrdinalIgnoreCase)).ToList());
|
|
if (!source.Any())
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem((_cache.Count == 0) ? "즐겨찾기가 없습니다" : ("'" + q + "'에 해당하는 즐겨찾기 없음"), "fav add [이름] [경로]로 추가하세요", null, null, null, "\ue946")));
|
|
}
|
|
List<LauncherItem> result = source.Select(delegate(FavEntry b)
|
|
{
|
|
bool flag = Directory.Exists(b.Path);
|
|
bool flag2 = File.Exists(b.Path);
|
|
string symbol = (flag ? "\ue8b7" : (flag2 ? "\ue8a5" : "\ue7ba"));
|
|
string text5 = (flag ? "폴더 열기" : (flag2 ? "파일 열기" : "경로를 찾을 수 없음"));
|
|
return new LauncherItem(b.Name, b.Path + " · " + text5, null, b.Path, null, symbol);
|
|
}).ToList();
|
|
return Task.FromResult((IEnumerable<LauncherItem>)result);
|
|
}
|
|
|
|
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
if (item.Data is (string, string, string) { Item1: "__ADD__" } tuple)
|
|
{
|
|
AddFav(tuple.Item2, tuple.Item3);
|
|
NotificationService.Notify("AX Copilot", "즐겨찾기 추가: " + tuple.Item2);
|
|
return Task.CompletedTask;
|
|
}
|
|
if (item.Data is (string, string) { Item1: "__DEL__" } tuple2)
|
|
{
|
|
RemoveFav(tuple2.Item2);
|
|
NotificationService.Notify("AX Copilot", "즐겨찾기 삭제: " + tuple2.Item2);
|
|
return Task.CompletedTask;
|
|
}
|
|
object data = item.Data;
|
|
string path = data as string;
|
|
if (path != null)
|
|
{
|
|
if (Directory.Exists(path) || File.Exists(path))
|
|
{
|
|
try
|
|
{
|
|
Process.Start(new ProcessStartInfo(path)
|
|
{
|
|
UseShellExecute = true
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("즐겨찾기 열기 실패: " + ex.Message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
Application current = Application.Current;
|
|
if (current != null)
|
|
{
|
|
((DispatcherObject)current).Dispatcher.Invoke((Action)delegate
|
|
{
|
|
Clipboard.SetText(path);
|
|
});
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private void EnsureLoaded()
|
|
{
|
|
if (_loaded)
|
|
{
|
|
return;
|
|
}
|
|
_loaded = true;
|
|
try
|
|
{
|
|
if (File.Exists(FavFile))
|
|
{
|
|
_cache = JsonSerializer.Deserialize<List<FavEntry>>(File.ReadAllText(FavFile), JsonOpts) ?? new List<FavEntry>();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("즐겨찾기 로드 실패: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private void AddFav(string name, string path)
|
|
{
|
|
EnsureLoaded();
|
|
_cache.RemoveAll((FavEntry b) => b.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
|
_cache.Insert(0, new FavEntry
|
|
{
|
|
Name = name,
|
|
Path = path
|
|
});
|
|
Save();
|
|
}
|
|
|
|
private void RemoveFav(string name)
|
|
{
|
|
EnsureLoaded();
|
|
_cache.RemoveAll((FavEntry b) => b.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
|
|
Save();
|
|
}
|
|
|
|
private void Save()
|
|
{
|
|
try
|
|
{
|
|
Directory.CreateDirectory(Path.GetDirectoryName(FavFile));
|
|
File.WriteAllText(FavFile, JsonSerializer.Serialize(_cache, JsonOpts));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("즐겨찾기 저장 실패: " + ex.Message);
|
|
}
|
|
}
|
|
}
|