using FluidExplorer.Services.Icons; using FluidExplorer.Services.Operations; using Microsoft.UI.Xaml.Media; namespace FluidExplorer.Services; /// /// 降级占位实现:当真实现(外壳图标服务 / 文件操作引擎)在构造阶段抛异常时兜底, /// 保证主界面还能打开浏览(图标为空、操作给出明确失败提示),而不是整个程序起不来。 /// internal sealed class PlaceholderIconService : IIconService { public Task GetIconAsync(string path, bool isDirectory, int size, CancellationToken cancellationToken) => Task.FromResult(null); public Task GetThumbnailAsync(string path, int size, CancellationToken cancellationToken) => Task.FromResult(null); public Task GetExtensionIconAsync(string extension, int size, CancellationToken cancellationToken) => Task.FromResult(null); public ImageSource? GetSpecialFolderIcon(string parsingName, int size) => null; public void ClearCache() { } } internal sealed class PlaceholderOperationService : IFileOperationService { private readonly List _jobs = []; public IReadOnlyList Jobs => _jobs; public event EventHandler? JobsChanged; // 占位实现永远不会产生撤销记录,事件显式忽略订阅以避免空事件告警 public event EventHandler? UndoStackChanged { add { } remove { } } public Func>? ConflictResolver { get; set; } public bool CanUndo => false; public string? UndoDescription => null; private FileOperationJob Fail(FileOperationKind kind, IReadOnlyList sources, string destination) { var job = new FileOperationJob { Kind = kind, Title = "文件操作服务不可用", Sources = sources, Destination = destination, State = JobState.Failed, Error = "文件操作引擎尚未接入。" }; _jobs.Add(job); JobsChanged?.Invoke(this, EventArgs.Empty); return job; } public FileOperationJob EnqueueCopy(IReadOnlyList sources, string destination, ConflictPolicy policy = ConflictPolicy.Ask) => Fail(FileOperationKind.Copy, sources, destination); public FileOperationJob EnqueueMove(IReadOnlyList sources, string destination, ConflictPolicy policy = ConflictPolicy.Ask) => Fail(FileOperationKind.Move, sources, destination); public FileOperationJob EnqueueDelete(IReadOnlyList paths, bool permanent = false) => Fail(FileOperationKind.Delete, paths, string.Empty); public FileOperationJob EnqueueRename(string path, string newName) => Fail(FileOperationKind.Rename, [path], newName); public FileOperationJob EnqueueNewFolder(string parentDirectory, string name) => Fail(FileOperationKind.NewFolder, [parentDirectory], name); public void Pause(Guid jobId) { } public void Resume(Guid jobId) { } public void Cancel(Guid jobId) { } public void ClearFinished() { } public Task UndoAsync(CancellationToken cancellationToken = default) => Task.FromResult(new OperationResult(false, 0, 0, 0, "没有可撤销的操作。")); public Task<(long Bytes, int Items)> MeasureAsync(IReadOnlyList paths, CancellationToken cancellationToken) => Task.FromResult((0L, 0)); }