GUI RootDriveInfo per type
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user