using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using FluidExplorer.Navigation; using FluidExplorer.Services.FileSystem; using FluidExplorer.Services.Search; using FluidExplorer.Services.Shell; using Microsoft.UI.Xaml.Media; namespace FluidExplorer.ViewModels; /// 侧边栏的一个节点(可展开的"此电脑"、可收藏的文件夹、驱动器等)。 public sealed partial class SidebarNode : ObservableObject { [ObservableProperty] private bool _isExpanded; [ObservableProperty] private bool _isSelected; public SidebarNode(string displayName, string glyph, NavigationLocation location, bool isExpandable = false) { DisplayName = displayName; Glyph = glyph; Location = location; IsExpandable = isExpandable; } public string DisplayName { get; } public string Glyph { get; } public NavigationLocation Location { get; } public bool IsExpandable { get; } public bool CanPin { get; init; } public ObservableCollection Children { get; } = []; public bool HasUnrealizedChildren { get; set; } /// 当前文件夹是否属于该节点(用于侧边栏高亮,对齐资源管理器)。 public bool Contains(string path) { if (string.IsNullOrEmpty(path)) return false; if (Location.Kind is LocationKind.ThisPc or LocationKind.RecycleBin or LocationKind.Network or LocationKind.Home) return string.Equals(Location.Path, path, StringComparison.OrdinalIgnoreCase); var root = Location.Path.TrimEnd('\\'); return path.StartsWith(root, StringComparison.OrdinalIgnoreCase); } public static SidebarNode Create(string name, string glyph, NavigationLocation location, bool expandable = false, bool canPin = false) => new(name, glyph, location, expandable) { CanPin = canPin }; } /// 面包屑的一段。 public sealed partial class BreadcrumbSegment : ObservableObject { public BreadcrumbSegment(string displayName, string path, bool isDriveRoot) { DisplayName = displayName; Path = path; IsDriveRoot = isDriveRoot; } public string DisplayName { get; } public string Path { get; } public bool IsDriveRoot { get; } } /// 搜索结果列表里的一行。 public sealed partial class SearchResultItem : ObservableObject { private ImageSource? _icon; private ImageSource? _thumbnail; public SearchResultItem(SearchHit hit) => Hit = hit; public SearchHit Hit { get; } public string Name => Hit.Name; public string Directory => Hit.Directory; public string FullPath => Hit.Path; public bool IsDirectory => Hit.IsDirectory; public long Size => Hit.Size; public string SizeText => Hit.Size < 0 ? "—" : Hit.IsDirectory ? string.Empty : Models.FileEntry.FormatSize(Hit.Size); public string ModifiedText => Hit.ModifiedUtc == DateTime.MinValue || Hit.ModifiedUtc == default ? "—" : Hit.ModifiedUtc.ToLocalTime().ToString("yyyy/MM/dd HH:mm"); public string TypeText => Hit.IsDirectory ? "文件夹" : TypeNameResolver.GetTypeName(Hit.Extension, false); public ImageSource? Icon { get => _icon; set { if (!ReferenceEquals(_icon, value)) { _icon = value; OnPropertyChanged(); } } } public ImageSource? Thumbnail { get => _thumbnail; set { if (!ReferenceEquals(_thumbnail, value)) { _thumbnail = value; OnPropertyChanged(); } } } public DateTime SortModified => Hit.ModifiedUtc; }