Element preview
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
namespace FileTime.App.Core.Models;
|
||||
|
||||
public record FileExtension(long? Size);
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace FileTime.App.Core.Models;
|
||||
|
||||
public enum ItemPreviewMode
|
||||
{
|
||||
Unknown,
|
||||
Text,
|
||||
Empty
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
|
||||
namespace FileTime.App.Core.Services;
|
||||
|
||||
public interface IItemPreviewService
|
||||
{
|
||||
IObservable<IItemPreviewViewModel?> ItemPreview { get; }
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.Core.Models;
|
||||
using InitableService;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public interface IFileViewModel : IElementViewModel, IInitable<IFileElement, ITabViewModel, ItemViewModelType>
|
||||
public interface IFileViewModel : IElementViewModel, IInitable<IElement, FileExtension, ITabViewModel, ItemViewModelType>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using FileTime.App.Core.Models;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels.ItemPreview;
|
||||
|
||||
public interface IItemPreviewViewModel
|
||||
{
|
||||
ItemPreviewMode Mode { get; }
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Reactive.Linq;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
using FileTime.Core.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.App.Core.Services;
|
||||
|
||||
public class ItemPreviewService : IItemPreviewService
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
public IObservable<IItemPreviewViewModel?> ItemPreview { get; }
|
||||
|
||||
public ItemPreviewService(IAppState appState, IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
ItemPreview = appState
|
||||
.SelectedTab
|
||||
.Select(t => t?.CurrentSelectedItem.Throttle(TimeSpan.FromMilliseconds(250)) ?? Observable.Return<IItemViewModel?>(null))
|
||||
.Switch()
|
||||
.Select(item =>
|
||||
item == null
|
||||
? Observable.Return<IItemPreviewViewModel?>(null)
|
||||
: Observable.FromAsync(async () => await Map(item))
|
||||
)
|
||||
.Switch()
|
||||
.Publish(null)
|
||||
.RefCount();
|
||||
}
|
||||
|
||||
private async Task<IItemPreviewViewModel?> Map(IItemViewModel itemViewModel)
|
||||
{
|
||||
return itemViewModel.BaseItem switch
|
||||
{
|
||||
IElement element => await _serviceProvider.GetAsyncInitableResolver(element)
|
||||
.GetRequiredServiceAsync<ElementPreviewViewModel>(),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.Services.UserCommandHandler;
|
||||
using FileTime.App.Core.StartupServices;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.App.Core;
|
||||
@@ -17,10 +18,12 @@ public static class Startup
|
||||
.AddTransient<IFileViewModel, FileViewModel>()
|
||||
.AddTransient<IContainerSizeContainerViewModel, ContainerSizeContainerViewModel>()
|
||||
.AddTransient<IItemNameConverterService, ItemNameConverterService>()
|
||||
.AddTransient<ElementPreviewViewModel>()
|
||||
.AddSingleton<IUserCommandHandlerService, UserCommandHandlerService>()
|
||||
.AddSingleton<IClipboardService, ClipboardService>()
|
||||
.AddSingleton<IIdentifiableUserCommandService, IdentifiableUserCommandService>()
|
||||
.AddSingleton<IStartupHandler, DefaultIdentifiableCommandHandlerRegister>()
|
||||
.AddSingleton<IItemPreviewService, ItemPreviewService>()
|
||||
.AddCommandHandlers();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.Core.Models;
|
||||
@@ -12,8 +13,9 @@ public partial class FileViewModel : ElementViewModel, IFileViewModel
|
||||
{
|
||||
}
|
||||
|
||||
public void Init(IFileElement item, ITabViewModel parentTab, ItemViewModelType itemViewModelType)
|
||||
public void Init(IElement item, FileExtension fileExtension, ITabViewModel parentTab, ItemViewModelType itemViewModelType)
|
||||
{
|
||||
Init((IElement)item, parentTab, itemViewModelType);
|
||||
Size = fileExtension.Size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Text;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.Core.Models;
|
||||
using InitableService;
|
||||
using MvvmGen;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels.ItemPreview;
|
||||
|
||||
[ViewModel]
|
||||
public partial class ElementPreviewViewModel : IItemPreviewViewModel, IAsyncInitable<IElement>
|
||||
{
|
||||
private const int MaxTextPreviewSize = 1024 * 1024;
|
||||
|
||||
public ItemPreviewMode Mode { get; private set; }
|
||||
|
||||
[Property] private string? _textContent;
|
||||
|
||||
public async Task InitAsync(IElement element)
|
||||
{
|
||||
try
|
||||
{
|
||||
var content = await element.Provider.GetContentAsync(element, MaxTextPreviewSize);
|
||||
|
||||
TextContent = content is null
|
||||
? "Could not read any data from file " + element.Name
|
||||
: Encoding.UTF8.GetString(content);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
TextContent = $"Error while getting content of {element.FullName}. " + ex.ToString();
|
||||
}
|
||||
|
||||
Mode = (TextContent?.Length ?? 0) switch
|
||||
{
|
||||
0 => ItemPreviewMode.Empty,
|
||||
_ => ItemPreviewMode.Text
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using FileTime.App.Core.Extensions;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -34,9 +35,14 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
public IObservable<IObservable<IChangeSet<IItemViewModel>>?> SelectedsChildren { get; private set; } = null!;
|
||||
public IObservable<IObservable<IChangeSet<IItemViewModel>>?> ParentsChildren { get; private set; } = null!;
|
||||
|
||||
public IObservable<IReadOnlyCollection<IItemViewModel>?> CurrentItemsCollectionObservable { get; private set; } = null!;
|
||||
public IObservable<IReadOnlyCollection<IItemViewModel>?> ParentsChildrenCollectionObservable { get; private set; } = null!;
|
||||
public IObservable<IReadOnlyCollection<IItemViewModel>?> SelectedsChildrenCollectionObservable { get; private set; } = null!;
|
||||
public IObservable<IReadOnlyCollection<IItemViewModel>?> CurrentItemsCollectionObservable { get; private set; } =
|
||||
null!;
|
||||
|
||||
public IObservable<IReadOnlyCollection<IItemViewModel>?> ParentsChildrenCollectionObservable { get; private set; } =
|
||||
null!;
|
||||
|
||||
public IObservable<IReadOnlyCollection<IItemViewModel>?>
|
||||
SelectedsChildrenCollectionObservable { get; private set; } = null!;
|
||||
|
||||
[Property] private BindedCollection<IItemViewModel>? _currentItemsCollection;
|
||||
|
||||
@@ -78,7 +84,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
tab.CurrentSelectedItem,
|
||||
(currentItems, currentSelectedItemPath) =>
|
||||
currentItems == null
|
||||
? Observable.Return((IItemViewModel?) null)
|
||||
? Observable.Return((IItemViewModel?)null)
|
||||
: currentItems
|
||||
.ToCollection()
|
||||
.Select(items =>
|
||||
@@ -117,7 +123,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
.Transform(i => MapItemToViewModel(i, ItemViewModelType.SelectedChild))),
|
||||
currentSelectedItemThrottled
|
||||
.Where(c => c is null or not IContainerViewModel)
|
||||
.Select(_ => (IObservable<IChangeSet<IItemViewModel>>?) null)
|
||||
.Select(_ => (IObservable<IChangeSet<IItemViewModel>>?)null)
|
||||
)
|
||||
/*.ObserveOn(_rxSchedulerService.GetWorkerScheduler())
|
||||
.SubscribeOn(_rxSchedulerService.GetUIScheduler())*/
|
||||
@@ -136,7 +142,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
return Observable.Merge(
|
||||
parentThrottled
|
||||
.Where(p => p is not null)
|
||||
.Select(p => Observable.FromAsync(async () => (IContainer) await p!.ResolveAsync()))
|
||||
.Select(p => Observable.FromAsync(async () => (IContainer)await p!.ResolveAsync()))
|
||||
.Switch()
|
||||
.Select(p => p.Items)
|
||||
.Switch()
|
||||
@@ -145,7 +151,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
.Transform(i => MapItemToViewModel(i, ItemViewModelType.Parent))),
|
||||
parentThrottled
|
||||
.Where(p => p is null)
|
||||
.Select(_ => (IObservable<IChangeSet<IItemViewModel>>?) null)
|
||||
.Select(_ => (IObservable<IChangeSet<IItemViewModel>>?)null)
|
||||
)
|
||||
/*.ObserveOn(_rxSchedulerService.GetWorkerScheduler())
|
||||
.SubscribeOn(_rxSchedulerService.GetUIScheduler())*/
|
||||
@@ -158,7 +164,7 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
{
|
||||
return source
|
||||
.Select(c =>
|
||||
c != null ? c.ToCollection() : Observable.Return((IReadOnlyCollection<IItemViewModel>?) null))
|
||||
c != null ? c.ToCollection() : Observable.Return((IReadOnlyCollection<IItemViewModel>?)null))
|
||||
.Switch()
|
||||
.Publish(null)
|
||||
.RefCount();
|
||||
@@ -179,22 +185,27 @@ public partial class TabViewModel : ITabViewModel, IDisposable
|
||||
|
||||
return containerViewModel;
|
||||
}
|
||||
else if (item is IFileElement fileElement)
|
||||
{
|
||||
var fileViewModel = _serviceProvider
|
||||
.GetInitableResolver<IFileElement, ITabViewModel, ItemViewModelType>(fileElement, this, type)
|
||||
.GetRequiredService<IFileViewModel>();
|
||||
fileViewModel.Size = fileElement.Size;
|
||||
|
||||
return fileViewModel;
|
||||
}
|
||||
else if (item is IElement element)
|
||||
{
|
||||
var elementViewModel = _serviceProvider
|
||||
.GetInitableResolver<IElement, ITabViewModel, ItemViewModelType>(element, this, type)
|
||||
.GetRequiredService<IElementViewModel>();
|
||||
var fileExtension = element.GetExtension<FileExtension>();
|
||||
|
||||
return elementViewModel;
|
||||
if (fileExtension is not null)
|
||||
{
|
||||
var fileViewModel = _serviceProvider
|
||||
.GetInitableResolver<IElement, FileExtension, ITabViewModel, ItemViewModelType>(
|
||||
element, fileExtension, this, type)
|
||||
.GetRequiredService<IFileViewModel>();
|
||||
|
||||
return fileViewModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var elementViewModel = _serviceProvider
|
||||
.GetInitableResolver<IElement, ITabViewModel, ItemViewModelType>(element, this, type)
|
||||
.GetRequiredService<IElementViewModel>();
|
||||
|
||||
return elementViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException($"{nameof(item)} is not {nameof(IContainer)} neither {nameof(IElement)}");
|
||||
|
||||
Reference in New Issue
Block a user