Skip to content

Commit aa39885

Browse files
Feature: View storage information for drives in the Details Pane (#16513)
1 parent 5e5e4f3 commit aa39885

File tree

7 files changed

+170
-12
lines changed

7 files changed

+170
-12
lines changed

src/Files.App.Controls/Storage/StorageBar/StorageBar.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
<Setter Property="TrackBarHeight" Value="{ThemeResource StorageBarTrackHeight}" />
1717
<Setter Property="CornerRadius" Value="{ThemeResource StorageBarCornerRadius}" />
1818
<Setter Property="VerticalAlignment" Value="Center" />
19-
<Setter Property="Width" Value="240" />
2019
<Setter Property="Minimum" Value="0" />
2120
<Setter Property="Maximum" Value="100" />
2221
<Setter Property="MinWidth" Value="32" />

src/Files.App/Data/Enums/PreviewPaneStates.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public enum PreviewPaneStates
3131
/// <summary>
3232
/// Loading preview status.
3333
/// </summary>
34-
LoadingPreview
34+
LoadingPreview,
35+
36+
/// <summary>
37+
/// Drive preview and details available status.
38+
/// </summary>
39+
DriveStorageDetailsAvailable,
3540
}
3641
}

src/Files.App/Data/Items/DriveItem.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT License. See the LICENSE.
33

44
using Files.App.Controls;
5-
using Files.App.Storage.Storables;
65
using Microsoft.UI.Xaml;
76
using Microsoft.UI.Xaml.Controls;
87
using Microsoft.UI.Xaml.Media.Imaging;
@@ -116,15 +115,27 @@ public bool ShowDriveDetails
116115
private DriveType type;
117116
public DriveType Type
118117
{
119-
get => type; set
118+
get => type;
119+
set
120120
{
121121
type = value;
122122

123123
if (value is DriveType.Network or DriveType.CloudDrive)
124124
ToolTip = Text;
125+
126+
OnPropertyChanged(nameof(TypeText));
125127
}
126128
}
127129

130+
public string TypeText => string.Format("DriveType{0}", Type).GetLocalizedResource();
131+
132+
private string filesystem = string.Empty;
133+
public string Filesystem
134+
{
135+
get => filesystem;
136+
set => SetProperty(ref filesystem, value);
137+
}
138+
128139
private string text;
129140
public string Text
130141
{
@@ -267,7 +278,7 @@ public async Task UpdatePropertiesAsync()
267278
{
268279
try
269280
{
270-
var properties = await Root.Properties.RetrievePropertiesAsync(["System.FreeSpace", "System.Capacity"])
281+
var properties = await Root.Properties.RetrievePropertiesAsync(["System.FreeSpace", "System.Capacity", "System.Volume.FileSystem"])
271282
.AsTask().WithTimeoutAsync(TimeSpan.FromSeconds(5));
272283

273284
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()
287298
MaxSpace = SpaceUsed = FreeSpace = ByteSize.FromBytes(0);
288299
}
289300

301+
if (properties is not null && properties["System.Volume.FileSystem"] is not null)
302+
Filesystem = (string)properties["System.Volume.FileSystem"];
303+
else
304+
Filesystem = string.Empty;
305+
290306
OnPropertyChanged(nameof(ShowDriveDetails));
291307
}
292308
catch (Exception)
293309
{
294310
SpaceText = "Unknown".GetLocalizedResource();
295311
MaxSpace = SpaceUsed = FreeSpace = ByteSize.FromBytes(0);
312+
Filesystem = string.Empty;
296313

297314
OnPropertyChanged(nameof(ShowDriveDetails));
298315
}

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4004,4 +4004,10 @@
40044004
<data name="ManageTags" xml:space="preserve">
40054005
<value>Manage tags</value>
40064006
</data>
4007+
<data name="Available" xml:space="preserve">
4008+
<value>Available</value>
4009+
</data>
4010+
<data name="Total" xml:space="preserve">
4011+
<value>Total</value>
4012+
</data>
40074013
</root>

src/Files.App/UserControls/Pane/InfoPane.xaml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,92 @@
238238
TextAlignment="Center"
239239
TextWrapping="Wrap"
240240
Visibility="Collapsed" />
241+
242+
<!-- Drive Details -->
243+
<TextBlock
244+
x:Name="DriveFormatAndTypeTextBlock"
245+
Margin="12,12,12,24"
246+
HorizontalAlignment="Center"
247+
IsTextSelectionEnabled="True"
248+
Style="{ThemeResource BodyTextBlockStyle}"
249+
TextAlignment="Center"
250+
TextWrapping="Wrap"
251+
Visibility="Collapsed">
252+
<Run Text="{x:Bind ViewModel.SelectedDriveItem.Filesystem, Mode=OneWay}" />
253+
<Run Foreground="{ThemeResource TextFillColorTertiaryBrush}" Text="{x:Bind ViewModel.SelectedDriveItem.TypeText, Mode=OneWay}" />
254+
</TextBlock>
255+
256+
<TextBlock
257+
x:Name="UsedSpaceTextBlock"
258+
HorizontalAlignment="Center"
259+
Foreground="{ThemeResource SystemAccentColor}"
260+
IsTextSelectionEnabled="True"
261+
Style="{ThemeResource SubtitleTextBlockStyle}"
262+
Text="{x:Bind ViewModel.SelectedDriveItem.UsedSpaceText, Mode=OneWay}"
263+
TextAlignment="Center"
264+
TextWrapping="Wrap"
265+
Visibility="Collapsed" />
266+
<controls:StorageBar
267+
x:Name="DriveSpaceProgressBar"
268+
Margin="8,8,8,8"
269+
HorizontalAlignment="Stretch"
270+
TrackBarHeight="4"
271+
ValueBarHeight="8"
272+
Visibility="Collapsed"
273+
Value="{x:Bind ViewModel.SelectedDriveItem.PercentageUsed, Mode=OneWay}" />
274+
<Grid
275+
x:Name="DriveSpaceGrid"
276+
Margin="12,0,12,24"
277+
Visibility="Collapsed">
278+
<Grid.RowDefinitions>
279+
<RowDefinition />
280+
<RowDefinition />
281+
</Grid.RowDefinitions>
282+
283+
<Grid.ColumnDefinitions>
284+
<ColumnDefinition Width="Auto" />
285+
<ColumnDefinition />
286+
<ColumnDefinition Width="Auto" />
287+
</Grid.ColumnDefinitions>
288+
289+
<TextBlock
290+
x:Name="AvailableSpaceTextBlock"
291+
FontFamily="{ThemeResource ContentControlThemeFontFamily}"
292+
FontSize="14"
293+
IsTextSelectionEnabled="True"
294+
Style="{ThemeResource BodyStrongTextBlockStyle}"
295+
Text="{x:Bind ViewModel.SelectedDriveItem.FreeSpaceText, Mode=OneWay}"
296+
TextAlignment="Left"
297+
TextWrapping="Wrap" />
298+
<TextBlock
299+
x:Name="TotalDriveSpaceTextBlock"
300+
Grid.Column="2"
301+
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
302+
IsTextSelectionEnabled="True"
303+
Style="{ThemeResource BodyStrongTextBlockStyle}"
304+
Text="{x:Bind ViewModel.SelectedDriveItem.MaxSpaceText, Mode=OneWay}"
305+
TextAlignment="Right"
306+
TextWrapping="Wrap" />
307+
<TextBlock
308+
x:Name="AvailableSpaceLabel"
309+
Grid.Row="1"
310+
HorizontalAlignment="Left"
311+
Style="{ThemeResource BodyTextBlockStyle}"
312+
Text="{helpers:ResourceString Name=Available}"
313+
TextAlignment="Left"
314+
TextWrapping="Wrap" />
315+
<TextBlock
316+
x:Name="TotalDriveSpaceLabel"
317+
Grid.Row="1"
318+
Grid.Column="2"
319+
HorizontalAlignment="Right"
320+
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
321+
Style="{ThemeResource BodyTextBlockStyle}"
322+
Text="{helpers:ResourceString Name=Total}"
323+
TextAlignment="Right"
324+
TextWrapping="Wrap" />
325+
</Grid>
326+
241327
<ItemsControl
242328
x:Name="FileDetailsRepeater"
243329
Margin="12,12,12,0"
@@ -467,6 +553,23 @@
467553
<Setter Target="PreviewLoadingIndicator.Visibility" Value="Visible" />
468554
</VisualState.Setters>
469555
</VisualState>
556+
<VisualState x:Name="DriveStorageDetailsAvailable">
557+
<VisualState.StateTriggers>
558+
<triggers:IsEqualStateTrigger Value="{x:Bind ViewModel.PreviewPaneState, Mode=OneWay}" To="5" />
559+
</VisualState.StateTriggers>
560+
<VisualState.Setters>
561+
<Setter Target="PreviewErrorText.Visibility" Value="Collapsed" />
562+
<Setter Target="FileDetailsRepeater.Visibility" Value="Collapsed" />
563+
<Setter Target="DetailsTagsList.Visibility" Value="Collapsed" />
564+
<Setter Target="DetailsOpenProperties.Visibility" Value="Visible" />
565+
<Setter Target="PreviewControlPresenter.Visibility" Value="Visible" />
566+
<Setter Target="DetailsListHeader.Visibility" Value="Visible" />
567+
<Setter Target="DriveFormatAndTypeTextBlock.Visibility" Value="Visible" />
568+
<Setter Target="UsedSpaceTextBlock.Visibility" Value="Visible" />
569+
<Setter Target="DriveSpaceProgressBar.Visibility" Value="Visible" />
570+
<Setter Target="DriveSpaceGrid.Visibility" Value="Visible" />
571+
</VisualState.Setters>
572+
</VisualState>
470573
</VisualStateGroup>
471574
<VisualStateGroup>
472575
<VisualState>

src/Files.App/ViewModels/UserControls/InfoPaneViewModel.cs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ namespace Files.App.ViewModels.UserControls
1414
public sealed class InfoPaneViewModel : ObservableObject, IDisposable
1515
{
1616
private IInfoPaneSettingsService infoPaneSettingsService { get; } = Ioc.Default.GetRequiredService<IInfoPaneSettingsService>();
17-
private IGeneralSettingsService generalSettingsService { get; } = Ioc.Default.GetRequiredService<IGeneralSettingsService>();
1817
private IContentPageContext contentPageContext { get; } = Ioc.Default.GetRequiredService<IContentPageContext>();
18+
private DrivesViewModel drivesViewModel { get; } = Ioc.Default.GetRequiredService<DrivesViewModel>();
1919

2020
private CancellationTokenSource loadCancellationTokenSource;
2121

@@ -50,6 +50,7 @@ public ListedItem? SelectedItem
5050
if (SetProperty(ref selectedItem, value))
5151
{
5252
UpdateTagsItems();
53+
SetDriveItem();
5354
OnPropertyChanged(nameof(LoadTagsList));
5455

5556
if (value is not null)
@@ -58,6 +59,19 @@ public ListedItem? SelectedItem
5859
}
5960
}
6061

62+
/// <summary>
63+
/// Current selected drive if any.
64+
/// </summary>
65+
private DriveItem? selectedDriveItem;
66+
public DriveItem? SelectedDriveItem
67+
{
68+
get => selectedDriveItem;
69+
set
70+
{
71+
SetProperty(ref selectedDriveItem, value);
72+
}
73+
}
74+
6175
/// <summary>
6276
/// Enum indicating whether to show the details or preview tab
6377
/// </summary>
@@ -177,7 +191,7 @@ private async Task LoadPreviewControlAsync(CancellationToken token, bool downloa
177191
if (control is not null)
178192
{
179193
PreviewPaneContent = control;
180-
PreviewPaneState = PreviewPaneStates.PreviewAndDetailsAvailable;
194+
PreviewPaneState = SelectedItem.IsDriveRoot ? PreviewPaneStates.DriveStorageDetailsAvailable : PreviewPaneStates.PreviewAndDetailsAvailable;
181195
return;
182196
}
183197

@@ -190,7 +204,7 @@ private async Task LoadPreviewControlAsync(CancellationToken token, bool downloa
190204
return;
191205

192206
PreviewPaneContent = control;
193-
PreviewPaneState = PreviewPaneStates.PreviewAndDetailsAvailable;
207+
PreviewPaneState = SelectedItem.IsDriveRoot ? PreviewPaneStates.DriveStorageDetailsAvailable : PreviewPaneStates.PreviewAndDetailsAvailable;
194208
}
195209

196210
private async Task<UserControl> GetBuiltInPreviewControlAsync(ListedItem item, bool downloadItem)
@@ -449,7 +463,7 @@ private async Task LoadBasicPreviewAsync()
449463
await basicModel.LoadAsync();
450464

451465
PreviewPaneContent = new BasicPreview(basicModel);
452-
PreviewPaneState = PreviewPaneStates.PreviewAndDetailsAvailable;
466+
PreviewPaneState = SelectedItem.IsDriveRoot ? PreviewPaneStates.DriveStorageDetailsAvailable : PreviewPaneStates.PreviewAndDetailsAvailable;
453467
}
454468
catch (Exception ex)
455469
{
@@ -474,6 +488,17 @@ private void UpdateTagsItems()
474488
Items.Add(new FlyoutItem(new Files.App.UserControls.Menus.FileTagsContextMenu(new List<ListedItem>() { SelectedItem })));
475489
}
476490

491+
private void SetDriveItem()
492+
{
493+
if (!(selectedItem?.IsDriveRoot ?? false))
494+
{
495+
selectedDriveItem = null;
496+
return;
497+
}
498+
499+
SelectedDriveItem = drivesViewModel.Drives.FirstOrDefault(drive => drive.Path == selectedItem.ItemPath) as DriveItem;
500+
}
501+
477502
public void Dispose()
478503
{
479504

src/Files.App/ViewModels/UserControls/Previews/FolderPreviewViewModel.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
using Files.App.ViewModels.Properties;
55
using Microsoft.UI.Xaml.Media.Imaging;
66
using System.IO;
7-
using Windows.Storage.FileProperties;
87

98
namespace Files.App.ViewModels.Previews
109
{
1110
public sealed class FolderPreviewViewModel
1211
{
13-
private static readonly IDateTimeFormatter dateTimeFormatter = Ioc.Default.GetRequiredService<IDateTimeFormatter>();
14-
1512
public ListedItem Item { get; }
1613

1714
public BitmapImage Thumbnail { get; set; } = new();
@@ -39,6 +36,12 @@ private async Task LoadPreviewAndDetailsAsync()
3936
if (result is not null)
4037
Thumbnail = await result.ToBitmapAsync();
4138

39+
// If the selected item is the root of a drive (e.g. "C:\")
40+
// we do not need to load the properties below, since they will not be shown.
41+
// Drive properties will be obtained through the DrivesViewModel service.
42+
if (Item.IsDriveRoot)
43+
return;
44+
4245
var info = await Folder.GetBasicPropertiesAsync();
4346

4447
Item.FileDetails =

0 commit comments

Comments
 (0)