Files
AX-Copilot-Codex/.decompiledproj/AxCopilot/Handlers/FavoriteHandler.cs

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);
}
}
}