Places (Windows only currently)

This commit is contained in:
2022-05-27 22:27:53 +02:00
parent 96158160bd
commit 03c8e3a36b
7 changed files with 111 additions and 35 deletions

View File

@@ -12,4 +12,5 @@ public interface IGuiAppState : IAppState
string? MessageBoxText { get; set; } string? MessageBoxText { get; set; }
List<CommandBindingConfiguration> PossibleCommands { get; set; } List<CommandBindingConfiguration> PossibleCommands { get; set; }
BindedCollection<RootDriveInfo, string> RootDriveInfos { get; set; } BindedCollection<RootDriveInfo, string> RootDriveInfos { get; set; }
IReadOnlyList<PlaceInfo> Places { get; set; }
} }

View File

@@ -0,0 +1,20 @@
using FileTime.Core.Models;
using FileTime.GuiApp.Models;
namespace FileTime.GuiApp.ViewModels;
public class PlaceInfo : IHaveFullPath
{
public IContainer Container { get; }
public string DisplayName { get; }
public PlaceInfo(IContainer container, string displayName)
{
if (container.FullName is null) throw new ArgumentNullException($"{nameof(container.FullName)} of container can not be null");
Container = container;
DisplayName = displayName;
}
public FullName Path => Container.FullName!;
}

View File

@@ -43,7 +43,8 @@ public static class Startup
serviceCollection.TryAddSingleton<IInputInterface>(s => s.GetRequiredService<IDialogService>()); serviceCollection.TryAddSingleton<IInputInterface>(s => s.GetRequiredService<IDialogService>());
return serviceCollection return serviceCollection
.AddSingleton<IStartupHandler, RootDriveInfoService>(); .AddSingleton<IStartupHandler, RootDriveInfoService>()
.AddSingleton<IStartupHandler, PlacesService>();
} }
internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection) internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection)

View File

@@ -19,5 +19,7 @@ public partial class GuiAppState : AppStateBase, IGuiAppState
[Property] private BindedCollection<RootDriveInfo, string> _rootDriveInfos = new(); [Property] private BindedCollection<RootDriveInfo, string> _rootDriveInfos = new();
[Property] private IReadOnlyList<PlaceInfo> _places;
public List<KeyConfig> PreviousKeys { get; } = new(); public List<KeyConfig> PreviousKeys { get; } = new();
} }

View File

@@ -0,0 +1,52 @@
using System.Runtime.InteropServices;
using FileTime.App.Core.Services;
using FileTime.Core.Models;
using FileTime.Core.Timeline;
using FileTime.GuiApp.ViewModels;
using FileTime.Providers.Local;
using Syroot.Windows.IO;
namespace FileTime.GuiApp.Services;
public class PlacesService : IStartupHandler
{
private readonly ILocalContentProvider _localContentProvider;
private readonly IGuiAppState _guiAppState;
public PlacesService(
ILocalContentProvider localContentProvider,
IGuiAppState guiAppState)
{
_localContentProvider = localContentProvider;
_guiAppState = guiAppState;
}
public async Task InitAsync()
{
var places = new List<PlaceInfo>();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var placesFolders = new List<KnownFolder>()
{
KnownFolders.Profile,
KnownFolders.Desktop,
KnownFolders.DocumentsLocalized,
KnownFolders.DownloadsLocalized,
KnownFolders.Music,
KnownFolders.Pictures,
KnownFolders.Videos,
};
foreach (var placesFolder in placesFolders)
{
var possibleContainer = await _localContentProvider.GetItemByNativePathAsync(new NativePath(placesFolder.Path), PointInTime.Present);
if (possibleContainer is not IContainer container) continue;
places.Add(new PlaceInfo(container, placesFolder.DisplayName));
}
}
_guiAppState.Places = places.AsReadOnly();
}
}

View File

@@ -8,23 +8,23 @@ using FileTime.Core.Models;
using FileTime.Core.Timeline; using FileTime.Core.Timeline;
using FileTime.GuiApp.ViewModels; using FileTime.GuiApp.ViewModels;
using FileTime.Providers.Local; using FileTime.Providers.Local;
using IContainer = FileTime.Core.Models.IContainer;
namespace FileTime.GuiApp.Services; namespace FileTime.GuiApp.Services;
public class RootDriveInfoService : IStartupHandler public class RootDriveInfoService : IStartupHandler
{ {
private readonly SourceList<DriveInfo> _rootDrives = new(); private readonly SourceList<DriveInfo> _rootDrives = new();
private readonly IObservable<IChangeSet<AbsolutePath, string>> _localContentProviderStream;
public RootDriveInfoService(IGuiAppState guiAppState, ILocalContentProvider localContentProvider, public RootDriveInfoService(
IGuiAppState guiAppState,
ILocalContentProvider localContentProvider,
ITimelessContentProvider timelessContentProvider) ITimelessContentProvider timelessContentProvider)
{ {
InitRootDrives(); InitRootDrives();
var localContentProviderAsList = new SourceCache<AbsolutePath, string>(i => i.Path.Path); var localContentProviderAsList = new SourceCache<AbsolutePath, string>(i => i.Path.Path);
localContentProviderAsList.AddOrUpdate(new AbsolutePath(timelessContentProvider, localContentProvider)); localContentProviderAsList.AddOrUpdate(new AbsolutePath(timelessContentProvider, localContentProvider));
_localContentProviderStream = localContentProviderAsList.Connect(); var localContentProviderStream = localContentProviderAsList.Connect();
var rootDriveInfos = Observable.CombineLatest( var rootDriveInfos = Observable.CombineLatest(
localContentProvider.Items, localContentProvider.Items,
@@ -34,7 +34,7 @@ public class RootDriveInfoService : IStartupHandler
return items is null return items is null
? Observable.Empty<IChangeSet<(AbsolutePath Path, DriveInfo? Drive), string>>() ? Observable.Empty<IChangeSet<(AbsolutePath Path, DriveInfo? Drive), string>>()
: items! : items!
.Or(new[] { _localContentProviderStream }) .Or(new[] { localContentProviderStream })
.Transform(i => (Path: i, Drive: drives.FirstOrDefault(d => .Transform(i => (Path: i, Drive: drives.FirstOrDefault(d =>
{ {
var containerPath = localContentProvider.GetNativePath(i.Path).Path; var containerPath = localContentProvider.GetNativePath(i.Path).Path;

View File

@@ -140,7 +140,7 @@
</Grid> </Grid>
</Border> </Border>
<!--Border Grid.Row="1" CornerRadius="10" Background="{DynamicResource ContainerBackgroundBrush}" Padding="0,10" Margin="10"> <Border Grid.Row="1" CornerRadius="10" Background="{DynamicResource ContainerBackgroundBrush}" Padding="0,10" Margin="10">
<Grid RowDefinitions="Auto,Auto"> <Grid RowDefinitions="Auto,Auto">
<TextBlock <TextBlock
@@ -149,9 +149,9 @@
<ItemsRepeater <ItemsRepeater
Grid.Row="1" Grid.Row="1"
Items="{Binding Places}"> Items="{Binding AppState.Places}">
<ItemsRepeater.ItemTemplate> <ItemsRepeater.ItemTemplate>
<DataTemplate> <DataTemplate x:DataType="vm:PlaceInfo">
<Grid Classes="SidebarContainerPresenter" PointerPressed="OnHasContainerPointerPressed" Cursor="Hand"> <Grid Classes="SidebarContainerPresenter" PointerPressed="OnHasContainerPointerPressed" Cursor="Hand">
<StackPanel Orientation="Horizontal" Margin="10,5" HorizontalAlignment="Stretch"> <StackPanel Orientation="Horizontal" Margin="10,5" HorizontalAlignment="Stretch">
<Image <Image
@@ -163,7 +163,7 @@
<TextBlock <TextBlock
Margin="5,0,0,0" Margin="5,0,0,0"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Name}" /> Text="{Binding DisplayName}" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
@@ -172,7 +172,7 @@
</Grid> </Grid>
</Border> </Border>
<Border Grid.Row="2" CornerRadius="10" Background="{DynamicResource ContainerBackgroundBrush}" Padding="0,10" Margin="10"> <!--Border Grid.Row="2" CornerRadius="10" Background="{DynamicResource ContainerBackgroundBrush}" Padding="0,10" Margin="10">
<Grid RowDefinitions="Auto,Auto"> <Grid RowDefinitions="Auto,Auto">
<TextBlock <TextBlock