GUI RootDriveInfo per type

This commit is contained in:
2023-09-06 09:47:37 +02:00
parent 67484ba56b
commit ef88885d40
5 changed files with 139 additions and 89 deletions

View File

@@ -1,4 +1,5 @@
using Avalonia; using System.Collections.ObjectModel;
using Avalonia;
using FileTime.App.CommandPalette.Services; using FileTime.App.CommandPalette.Services;
using FileTime.App.Core.Services; using FileTime.App.Core.Services;
using FileTime.App.Core.ViewModels; using FileTime.App.Core.ViewModels;
@@ -24,8 +25,9 @@ public interface IMainWindowViewModel : IMainWindowViewModelBase
ITimelineViewModel TimelineViewModel { get; } ITimelineViewModel TimelineViewModel { get; }
IPossibleCommandsViewModel PossibleCommands { get; } IPossibleCommandsViewModel PossibleCommands { get; }
ICloudDriveService CloudDriveService { get; } ICloudDriveService CloudDriveService { get; }
IRootDriveInfoService RootDriveInfoService { get; }
Action? ShowWindow { get; set; } Action? ShowWindow { get; set; }
Thickness IconStatusPanelMargin { get; } Thickness IconStatusPanelMargin { get; }
ObservableCollection<RootDriveInfo> LocalDrives { get; set; }
ObservableCollection<RootDriveInfo> NetworkDrives { get; set; }
Task RunOrOpenItem(IItemViewModel itemViewModel); Task RunOrOpenItem(IItemViewModel itemViewModel);
} }

View File

@@ -1,4 +1,5 @@
using System.Reactive.Linq; using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia; using Avalonia;
@@ -20,6 +21,7 @@ using FileTime.Providers.Local;
using FileTime.Providers.LocalAdmin; using FileTime.Providers.LocalAdmin;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MvvmGen; using MvvmGen;
using ObservableComputations;
namespace FileTime.GuiApp.App.ViewModels; namespace FileTime.GuiApp.App.ViewModels;
@@ -45,9 +47,10 @@ namespace FileTime.GuiApp.App.ViewModels;
[Inject(typeof(IPossibleCommandsViewModel), PropertyName = "PossibleCommands", PropertyAccessModifier = AccessModifier.Public)] [Inject(typeof(IPossibleCommandsViewModel), PropertyName = "PossibleCommands", PropertyAccessModifier = AccessModifier.Public)]
[Inject(typeof(IInstanceMessageHandler), PropertyName = "_instanceMessageHandler")] [Inject(typeof(IInstanceMessageHandler), PropertyName = "_instanceMessageHandler")]
[Inject(typeof(ICloudDriveService), PropertyAccessModifier = AccessModifier.Public)] [Inject(typeof(ICloudDriveService), PropertyAccessModifier = AccessModifier.Public)]
[Inject(typeof(IRootDriveInfoService), PropertyAccessModifier = AccessModifier.Public)] [Inject(typeof(IRootDriveInfoService), PropertyName = "_rootDriveInfoService")]
public partial class MainWindowViewModel : IMainWindowViewModel public partial class MainWindowViewModel : IMainWindowViewModel
{ {
private readonly OcConsumer _rootDriveInfosConsumer = new();
public bool Loading => false; public bool Loading => false;
public IObservable<string?> MainFont => _fontService.MainFont.Select(x => x ?? ""); public IObservable<string?> MainFont => _fontService.MainFont.Select(x => x ?? "");
public DeclarativeProperty<string> FatalError { get; } = new(); public DeclarativeProperty<string> FatalError { get; } = new();
@@ -58,6 +61,9 @@ public partial class MainWindowViewModel : IMainWindowViewModel
public Action? FocusDefaultElement { get; set; } public Action? FocusDefaultElement { get; set; }
public Action? ShowWindow { get; set; } public Action? ShowWindow { get; set; }
public ObservableCollection<RootDriveInfo> LocalDrives { get; set; }
public ObservableCollection<RootDriveInfo> NetworkDrives { get; set; }
partial void OnInitialize() partial void OnInitialize()
{ {
_logger.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization..."); _logger.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization...");
@@ -84,6 +90,15 @@ public partial class MainWindowViewModel : IMainWindowViewModel
#endif #endif
Title.SetValueSafe(title); Title.SetValueSafe(title);
var localDrives = _rootDriveInfoService.RootDriveInfos.Filtering(r => r.DriveType != DriveType.Network);
var networkDrives = _rootDriveInfoService.RootDriveInfos.Filtering(r => r.DriveType == DriveType.Network);
localDrives.For(_rootDriveInfosConsumer);
networkDrives.For(_rootDriveInfosConsumer);
LocalDrives = localDrives;
NetworkDrives = networkDrives;
_modalService.AllModalClosed += (_, _) => FocusDefaultElement?.Invoke(); _modalService.AllModalClosed += (_, _) => FocusDefaultElement?.Invoke();
_instanceMessageHandler.ShowWindow += () => ShowWindow?.Invoke(); _instanceMessageHandler.ShowWindow += () => ShowWindow?.Invoke();

View File

@@ -41,6 +41,82 @@
<ResourceInclude Source="avares://FileTime.GuiApp.App/Resources/SolarizedDarkTheme.axaml" /> <ResourceInclude Source="avares://FileTime.GuiApp.App/Resources/SolarizedDarkTheme.axaml" />
<ResourceInclude Source="avares://FileTime.GuiApp.App/Resources/Brushes.axaml" /> <ResourceInclude Source="avares://FileTime.GuiApp.App/Resources/Brushes.axaml" />
<ResourceInclude Source="avares://FileTime.GuiApp.App/Resources/Converters.axaml" /> <ResourceInclude Source="avares://FileTime.GuiApp.App/Resources/Converters.axaml" />
<ResourceDictionary>
<DataTemplate
x:Key="RootDriveTemplate"
x:DataType="local1:RootDriveInfo">
<Grid
Classes="SidebarContainerPresenter"
PointerPressed="OnHasContainerPointerPressed"
ToolTip.Tip="{Binding FullName}">
<Grid
Margin="10,5"
ColumnDefinitions="Auto,*,Auto"
RowDefinitions="Auto,Auto">
<Image
Grid.RowSpan="2"
Width="20"
Height="20"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Source="{SvgImage /Assets/material/folder.svg}" />
<StackPanel
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Text="{Binding Name}" />
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Classes="ExtraSmallText"
IsVisible="{Binding Label, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Text="{Binding Label}" />
</StackPanel>
<StackPanel
Grid.Row="0"
Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Classes="SmallText"
Text="{Binding Free, Converter={StaticResource FormatSizeConverter}}" />
<TextBlock
VerticalAlignment="Center"
Classes="SmallText"
Text=" / " />
<TextBlock
VerticalAlignment="Center"
Classes="SmallText"
Text="{Binding Size, Converter={StaticResource FormatSizeConverter}}" />
</StackPanel>
<ProgressBar
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"
MinWidth="100"
Margin="5,0,0,0"
HorizontalAlignment="Stretch"
Maximum="100"
Value="{Binding UsedPercentage}" />
</Grid>
</Grid>
</DataTemplate>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Window.Resources> </Window.Resources>
@@ -111,103 +187,49 @@
</Grid> </Grid>
</Grid> </Grid>
<Grid <StackPanel
Grid.Row="1" Grid.Row="1"
RowDefinitions="Auto,Auto,Auto,Auto"> Grid.Column="0">
<Border <Border
Margin="10" Margin="10"
Padding="0,10" Padding="0,10"
Background="{DynamicResource ContainerBackgroundBrush}" Background="{DynamicResource ContainerBackgroundBrush}"
CornerRadius="10"> CornerRadius="10"
IsVisible="{Binding LocalDrives.Count, Converter={StaticResource GreaterThanConverter}, ConverterParameter=0}">
<Grid RowDefinitions="Auto,Auto"> <Grid RowDefinitions="Auto,Auto">
<TextBlock <TextBlock
Margin="10,0,10,10" Margin="10,0,10,10"
Text="Drives" /> Text="Local drives" />
<ItemsRepeater <ItemsRepeater
Grid.Row="1" Grid.Row="1"
ItemsSource="{Binding RootDriveInfoService.RootDriveInfos}"> ItemTemplate="{StaticResource RootDriveTemplate}"
<ItemsRepeater.ItemTemplate> ItemsSource="{Binding LocalDrives}" />
<DataTemplate x:DataType="local1:RootDriveInfo"> </Grid>
<Grid </Border>
Classes="SidebarContainerPresenter"
PointerPressed="OnHasContainerPointerPressed" <Border
ToolTip.Tip="{Binding FullName}"> Margin="10"
<Grid Padding="0,10"
Margin="10,5" Background="{DynamicResource ContainerBackgroundBrush}"
ColumnDefinitions="Auto,*,Auto" CornerRadius="10"
RowDefinitions="Auto,Auto"> IsVisible="{Binding NetworkDrives.Count, Converter={StaticResource GreaterThanConverter}, ConverterParameter=0}">
<Image <Grid RowDefinitions="Auto,Auto">
Grid.RowSpan="2"
Width="20" <TextBlock
Height="20" Margin="10,0,10,10"
HorizontalAlignment="Left" Text="Network drives" />
VerticalAlignment="Center"
Source="{SvgImage /Assets/material/folder.svg}" /> <ItemsRepeater
Grid.Row="1"
<StackPanel ItemTemplate="{StaticResource RootDriveTemplate}"
Grid.Row="0" ItemsSource="{Binding NetworkDrives}" />
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Text="{Binding Name}" />
<TextBlock
Margin="5,0,0,0"
VerticalAlignment="Center"
Classes="ExtraSmallText"
IsVisible="{Binding Label, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
Text="{Binding Label}" />
</StackPanel>
<StackPanel
Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Classes="SmallText"
Text="{Binding Free, Converter={StaticResource FormatSizeConverter}}" />
<TextBlock
VerticalAlignment="Center"
Classes="SmallText"
Text=" / " />
<TextBlock
VerticalAlignment="Center"
Classes="SmallText"
Text="{Binding Size, Converter={StaticResource FormatSizeConverter}}" />
</StackPanel>
<ProgressBar
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"
MinWidth="100"
Margin="5,0,0,0"
HorizontalAlignment="Stretch"
Maximum="100"
Value="{Binding UsedPercentage}" />
</Grid>
</Grid>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</Grid> </Grid>
</Border> </Border>
<Border <Border
Grid.Row="1"
Margin="10" Margin="10"
Padding="0,10" Padding="0,10"
Background="{DynamicResource ContainerBackgroundBrush}" Background="{DynamicResource ContainerBackgroundBrush}"
@@ -250,7 +272,6 @@
</Border> </Border>
<Border <Border
Grid.Row="2"
Margin="10" Margin="10"
Padding="0,10" Padding="0,10"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
@@ -295,7 +316,6 @@
</Border> </Border>
<Border <Border
Grid.Row="3"
Margin="10" Margin="10"
Padding="10" Padding="10"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
@@ -318,7 +338,7 @@
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </StackPanel>
<Grid <Grid
Grid.Row="1" Grid.Row="1"

View File

@@ -20,6 +20,8 @@ public partial class RootDriveInfo
[Notify] private long _free; [Notify] private long _free;
[Notify] private long _used; [Notify] private long _used;
public DriveType DriveType => _driveInfo.DriveType;
public long UsedPercentage => Size == 0 ? 0 : Used * 100 / Size; public long UsedPercentage => Size == 0 ? 0 : Used * 100 / Size;

View File

@@ -34,13 +34,14 @@ public class RootDriveInfoService : IRootDriveInfoService
var rootDriveInfos = _rootDrives.Selecting(r => GetContainer(r)) var rootDriveInfos = _rootDrives.Selecting(r => GetContainer(r))
.Filtering(t => t.Item != null) .Filtering(t => t.Item != null)
.Selecting(t => new RootDriveInfo(t.Drive, t.Item!)) .Selecting(t => new RootDriveInfo(t.Drive, t.Item!))
.Ordering(d => d.Name) .Ordering(d => GetDriveOrder(d.DriveType))
.ThenOrdering(d => d.Name)
.For(_rootDriveInfosConsumer); .For(_rootDriveInfosConsumer);
RootDriveInfos = new ReadOnlyObservableCollection<RootDriveInfo>(rootDriveInfos); RootDriveInfos = new ReadOnlyObservableCollection<RootDriveInfo>(rootDriveInfos);
AllDrives = new ReadOnlyObservableCollection<DriveInfo>(_allDrives); AllDrives = new ReadOnlyObservableCollection<DriveInfo>(_allDrives);
(DriveInfo[] RootDrives, DriveInfo[] AllDrives) GetRootDrives() static (DriveInfo[] RootDrives, DriveInfo[] AllDrives) GetRootDrives()
{ {
var allDrives = DriveInfo.GetDrives(); var allDrives = DriveInfo.GetDrives();
var drives = DriveInfo.GetDrives().Where(d => d.DriveType is not DriveType.Unknown and not DriveType.Ram); var drives = DriveInfo.GetDrives().Where(d => d.DriveType is not DriveType.Unknown and not DriveType.Ram);
@@ -70,6 +71,16 @@ public class RootDriveInfoService : IRootDriveInfoService
return (rootDriveInfo, task.Result as IContainer); return (rootDriveInfo, task.Result as IContainer);
} }
private static int GetDriveOrder(DriveType type)
=> type switch
{
DriveType.Fixed => 0,
DriveType.Removable => 1,
DriveType.CDRom => 2,
DriveType.Network => 3,
_ => 5
};
public Task ExitAsync(CancellationToken token = default) public Task ExitAsync(CancellationToken token = default)
{ {
_rootDriveInfosConsumer.Dispose(); _rootDriveInfosConsumer.Dispose();