diff --git a/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml b/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml index 2ec064794152..2b870e823380 100644 --- a/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml +++ b/src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml @@ -16,7 +16,6 @@ - diff --git a/src/Files.App/Data/Enums/PreviewPaneStates.cs b/src/Files.App/Data/Enums/PreviewPaneStates.cs index 36e076f797dd..35d9c8cc1aef 100644 --- a/src/Files.App/Data/Enums/PreviewPaneStates.cs +++ b/src/Files.App/Data/Enums/PreviewPaneStates.cs @@ -31,6 +31,11 @@ public enum PreviewPaneStates /// /// Loading preview status. /// - LoadingPreview + LoadingPreview, + + /// + /// Drive preview and details available status. + /// + DriveStorageDetailsAvailable, } } diff --git a/src/Files.App/Data/Items/DriveItem.cs b/src/Files.App/Data/Items/DriveItem.cs index b624f0c2161b..12f1edf930b8 100644 --- a/src/Files.App/Data/Items/DriveItem.cs +++ b/src/Files.App/Data/Items/DriveItem.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. See the LICENSE. using Files.App.Controls; -using Files.App.Storage.Storables; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media.Imaging; @@ -116,15 +115,27 @@ public bool ShowDriveDetails private DriveType type; public DriveType Type { - get => type; set + get => type; + set { type = value; if (value is DriveType.Network or DriveType.CloudDrive) ToolTip = Text; + + OnPropertyChanged(nameof(TypeText)); } } + public string TypeText => string.Format("DriveType{0}", Type).GetLocalizedResource(); + + private string filesystem = string.Empty; + public string Filesystem + { + get => filesystem; + set => SetProperty(ref filesystem, value); + } + private string text; public string Text { @@ -267,7 +278,7 @@ public async Task UpdatePropertiesAsync() { try { - var properties = await Root.Properties.RetrievePropertiesAsync(["System.FreeSpace", "System.Capacity"]) + var properties = await Root.Properties.RetrievePropertiesAsync(["System.FreeSpace", "System.Capacity", "System.Volume.FileSystem"]) .AsTask().WithTimeoutAsync(TimeSpan.FromSeconds(5)); if (properties is not null && properties["System.Capacity"] is not null && properties["System.FreeSpace"] is not null) @@ -287,12 +298,18 @@ public async Task UpdatePropertiesAsync() MaxSpace = SpaceUsed = FreeSpace = ByteSize.FromBytes(0); } + if (properties is not null && properties["System.Volume.FileSystem"] is not null) + Filesystem = (string)properties["System.Volume.FileSystem"]; + else + Filesystem = string.Empty; + OnPropertyChanged(nameof(ShowDriveDetails)); } catch (Exception) { SpaceText = "Unknown".GetLocalizedResource(); MaxSpace = SpaceUsed = FreeSpace = ByteSize.FromBytes(0); + Filesystem = string.Empty; OnPropertyChanged(nameof(ShowDriveDetails)); } diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index f4ddb611460d..47eaba2151d1 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -4004,4 +4004,10 @@ Manage tags + + Available + + + Total + \ No newline at end of file diff --git a/src/Files.App/UserControls/Pane/InfoPane.xaml b/src/Files.App/UserControls/Pane/InfoPane.xaml index b06eee2debbd..84210302b8a6 100644 --- a/src/Files.App/UserControls/Pane/InfoPane.xaml +++ b/src/Files.App/UserControls/Pane/InfoPane.xaml @@ -238,6 +238,92 @@ TextAlignment="Center" TextWrapping="Wrap" Visibility="Collapsed" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Files.App/ViewModels/UserControls/InfoPaneViewModel.cs b/src/Files.App/ViewModels/UserControls/InfoPaneViewModel.cs index 22f93fe1a699..8dfbc9490970 100644 --- a/src/Files.App/ViewModels/UserControls/InfoPaneViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/InfoPaneViewModel.cs @@ -14,8 +14,8 @@ namespace Files.App.ViewModels.UserControls public sealed class InfoPaneViewModel : ObservableObject, IDisposable { private IInfoPaneSettingsService infoPaneSettingsService { get; } = Ioc.Default.GetRequiredService(); - private IGeneralSettingsService generalSettingsService { get; } = Ioc.Default.GetRequiredService(); private IContentPageContext contentPageContext { get; } = Ioc.Default.GetRequiredService(); + private DrivesViewModel drivesViewModel { get; } = Ioc.Default.GetRequiredService(); private CancellationTokenSource loadCancellationTokenSource; @@ -50,6 +50,7 @@ public ListedItem? SelectedItem if (SetProperty(ref selectedItem, value)) { UpdateTagsItems(); + SetDriveItem(); OnPropertyChanged(nameof(LoadTagsList)); if (value is not null) @@ -58,6 +59,19 @@ public ListedItem? SelectedItem } } + /// + /// Current selected drive if any. + /// + private DriveItem? selectedDriveItem; + public DriveItem? SelectedDriveItem + { + get => selectedDriveItem; + set + { + SetProperty(ref selectedDriveItem, value); + } + } + /// /// Enum indicating whether to show the details or preview tab /// @@ -177,7 +191,7 @@ private async Task LoadPreviewControlAsync(CancellationToken token, bool downloa if (control is not null) { PreviewPaneContent = control; - PreviewPaneState = PreviewPaneStates.PreviewAndDetailsAvailable; + PreviewPaneState = SelectedItem.IsDriveRoot ? PreviewPaneStates.DriveStorageDetailsAvailable : PreviewPaneStates.PreviewAndDetailsAvailable; return; } @@ -190,7 +204,7 @@ private async Task LoadPreviewControlAsync(CancellationToken token, bool downloa return; PreviewPaneContent = control; - PreviewPaneState = PreviewPaneStates.PreviewAndDetailsAvailable; + PreviewPaneState = SelectedItem.IsDriveRoot ? PreviewPaneStates.DriveStorageDetailsAvailable : PreviewPaneStates.PreviewAndDetailsAvailable; } private async Task GetBuiltInPreviewControlAsync(ListedItem item, bool downloadItem) @@ -449,7 +463,7 @@ private async Task LoadBasicPreviewAsync() await basicModel.LoadAsync(); PreviewPaneContent = new BasicPreview(basicModel); - PreviewPaneState = PreviewPaneStates.PreviewAndDetailsAvailable; + PreviewPaneState = SelectedItem.IsDriveRoot ? PreviewPaneStates.DriveStorageDetailsAvailable : PreviewPaneStates.PreviewAndDetailsAvailable; } catch (Exception ex) { @@ -474,6 +488,17 @@ private void UpdateTagsItems() Items.Add(new FlyoutItem(new Files.App.UserControls.Menus.FileTagsContextMenu(new List() { SelectedItem }))); } + private void SetDriveItem() + { + if (!(selectedItem?.IsDriveRoot ?? false)) + { + selectedDriveItem = null; + return; + } + + SelectedDriveItem = drivesViewModel.Drives.FirstOrDefault(drive => drive.Path == selectedItem.ItemPath) as DriveItem; + } + public void Dispose() { diff --git a/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs index f826df056e35..45f9421308d7 100644 --- a/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs @@ -4,14 +4,11 @@ using Files.App.ViewModels.Properties; using Microsoft.UI.Xaml.Media.Imaging; using System.IO; -using Windows.Storage.FileProperties; namespace Files.App.ViewModels.Previews { public sealed class FolderPreviewViewModel { - private static readonly IDateTimeFormatter dateTimeFormatter = Ioc.Default.GetRequiredService(); - public ListedItem Item { get; } public BitmapImage Thumbnail { get; set; } = new(); @@ -39,6 +36,12 @@ private async Task LoadPreviewAndDetailsAsync() if (result is not null) Thumbnail = await result.ToBitmapAsync(); + // If the selected item is the root of a drive (e.g. "C:\") + // we do not need to load the properties below, since they will not be shown. + // Drive properties will be obtained through the DrivesViewModel service. + if (Item.IsDriveRoot) + return; + var info = await Folder.GetBasicPropertiesAsync(); Item.FileDetails =