Console Binary file preview
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.ConsoleUI.App.Preview;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
|
||||
namespace FileTime.ConsoleUI.App;
|
||||
@@ -9,4 +10,6 @@ public partial class ConsoleAppState : AppStateBase, IConsoleAppState
|
||||
[Notify] private string? _errorText;
|
||||
//TODO: make it thread safe
|
||||
public ObservableCollection<string> PopupTexts { get; } = new();
|
||||
|
||||
[Notify] private ItemPreviewType? _previewType = ItemPreviewType.Binary;
|
||||
}
|
||||
@@ -105,13 +105,13 @@ public class CommandPalette
|
||||
|
||||
item.Bind(
|
||||
item.Parent,
|
||||
d => d.CommandPalette.SelectedItem == item.DataContext ? _theme.ListViewItemTheme.SelectedBackgroundColor : null,
|
||||
d => d.CommandPalette.SelectedItem.Identifier == item.DataContext.Identifier ? _theme.ListViewItemTheme.SelectedBackgroundColor : null,
|
||||
t => t.Background
|
||||
);
|
||||
|
||||
item.Bind(
|
||||
item.Parent,
|
||||
d => d.CommandPalette.SelectedItem == item.DataContext ? _theme.ListViewItemTheme.SelectedForegroundColor : null,
|
||||
d => d.CommandPalette.SelectedItem.Identifier == item.DataContext.Identifier ? _theme.ListViewItemTheme.SelectedForegroundColor : null,
|
||||
t => t.Foreground
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
using FileTime.ConsoleUI.App.Preview;
|
||||
using FileTime.ConsoleUI.App.Styling;
|
||||
using TerminalUI.Controls;
|
||||
using TerminalUI.Extensions;
|
||||
@@ -11,10 +12,12 @@ namespace FileTime.ConsoleUI.App.Controls;
|
||||
public class ItemPreviews
|
||||
{
|
||||
private readonly ITheme _theme;
|
||||
private readonly IConsoleAppState _appState;
|
||||
|
||||
public ItemPreviews(ITheme theme)
|
||||
public ItemPreviews(ITheme theme, IConsoleAppState appState)
|
||||
{
|
||||
_theme = theme;
|
||||
_appState = appState;
|
||||
}
|
||||
|
||||
public IView<IRootViewModel> View()
|
||||
@@ -75,11 +78,34 @@ public class ItemPreviews
|
||||
ChildInitializer =
|
||||
{
|
||||
new TextBlock<IElementPreviewViewModel>()
|
||||
.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.TextContent,
|
||||
t => t.Text,
|
||||
fallbackValue: string.Empty)),
|
||||
.Setup(t =>
|
||||
{
|
||||
t.Bind(
|
||||
t,
|
||||
dc => dc.TextContent,
|
||||
t => t.Text,
|
||||
fallbackValue: string.Empty);
|
||||
|
||||
t.Bind(
|
||||
t,
|
||||
dc => _appState.PreviewType,
|
||||
t => t.IsVisible,
|
||||
v => v is null or ItemPreviewType.Text);
|
||||
}),
|
||||
new BinaryView<IElementPreviewViewModel>()
|
||||
.Setup(b =>
|
||||
{
|
||||
b.Bind(
|
||||
b,
|
||||
dc => dc.BinaryContent,
|
||||
b => b.Data);
|
||||
|
||||
b.Bind(
|
||||
b,
|
||||
dc => _appState.PreviewType,
|
||||
t => t.IsVisible,
|
||||
v => v == ItemPreviewType.Binary);
|
||||
}),
|
||||
new TextBlock<IElementPreviewViewModel>
|
||||
{
|
||||
Margin = "0 1 0 0",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Globalization;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.ConsoleUI.App.Configuration;
|
||||
using FileTime.ConsoleUI.App.Controls;
|
||||
using FileTime.ConsoleUI.App.Styling;
|
||||
using FileTime.Core.Enums;
|
||||
using FileTime.Core.Models;
|
||||
using Humanizer.Bytes;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TerminalUI;
|
||||
using TerminalUI.Color;
|
||||
using TerminalUI.Controls;
|
||||
@@ -36,6 +38,7 @@ public class MainWindow
|
||||
private readonly Dialogs _dialogs;
|
||||
private readonly Timeline _timeline;
|
||||
private readonly ItemPreviews _itemPreviews;
|
||||
private readonly IOptions<ConsoleApplicationConfiguration> _consoleApplicationConfiguration;
|
||||
private readonly Lazy<IView> _root;
|
||||
|
||||
|
||||
@@ -47,7 +50,8 @@ public class MainWindow
|
||||
FrequencyNavigation frequencyNavigation,
|
||||
Dialogs dialogs,
|
||||
Timeline timeline,
|
||||
ItemPreviews itemPreviews)
|
||||
ItemPreviews itemPreviews,
|
||||
IOptions<ConsoleApplicationConfiguration> consoleApplicationConfiguration)
|
||||
{
|
||||
_rootViewModel = rootViewModel;
|
||||
_applicationContext = applicationContext;
|
||||
@@ -57,6 +61,7 @@ public class MainWindow
|
||||
_dialogs = dialogs;
|
||||
_timeline = timeline;
|
||||
_itemPreviews = itemPreviews;
|
||||
_consoleApplicationConfiguration = consoleApplicationConfiguration;
|
||||
_root = new Lazy<IView>(Initialize);
|
||||
}
|
||||
|
||||
@@ -92,7 +97,7 @@ public class MainWindow
|
||||
{
|
||||
new Grid<IRootViewModel>
|
||||
{
|
||||
ColumnDefinitionsObject = "Auto * Auto",
|
||||
ColumnDefinitionsObject = "Auto * Auto Auto",
|
||||
ChildInitializer =
|
||||
{
|
||||
new StackPanel<IRootViewModel>
|
||||
@@ -130,8 +135,32 @@ public class MainWindow
|
||||
root => root.AppState.SelectedTab.Value.CurrentLocation.Value.FullName.Path,
|
||||
tb => tb.Text
|
||||
)),
|
||||
new StackPanel<IRootViewModel>
|
||||
{
|
||||
Margin = "2 0 0 0",
|
||||
Extensions = {new GridPositionExtension(2, 0)},
|
||||
ChildInitializer =
|
||||
{
|
||||
new TextBlock<IRootViewModel>
|
||||
{
|
||||
Text = _consoleApplicationConfiguration.Value.ClipboardSingleIcon ?? "C",
|
||||
AsciiOnly = false
|
||||
}.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.ClipboardService.Content.Count == 1,
|
||||
t => t.IsVisible)),
|
||||
new TextBlock<IRootViewModel>
|
||||
{
|
||||
Text = _consoleApplicationConfiguration.Value.ClipboardMultipleIcon ?? "CC",
|
||||
AsciiOnly = false
|
||||
}.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.ClipboardService.Content.Count > 1,
|
||||
t => t.IsVisible))
|
||||
}
|
||||
},
|
||||
TabControl()
|
||||
.WithExtension(new GridPositionExtension(2, 0))
|
||||
.WithExtension(new GridPositionExtension(3, 0))
|
||||
}
|
||||
},
|
||||
new Grid<IRootViewModel>
|
||||
@@ -375,6 +404,7 @@ public class MainWindow
|
||||
{
|
||||
var tabList = new ListView<IRootViewModel, ITabViewModel>
|
||||
{
|
||||
Margin = "1 0 0 0",
|
||||
Orientation = Orientation.Horizontal,
|
||||
ItemTemplate = item =>
|
||||
{
|
||||
|
||||
@@ -4,13 +4,15 @@ using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.App.Core.ViewModels.Timeline;
|
||||
using FileTime.App.FrequencyNavigation.ViewModels;
|
||||
using FileTime.ConsoleUI.App.Preview;
|
||||
using FileTime.ConsoleUI.App.Services;
|
||||
using FileTime.Core.Interactions;
|
||||
using FileTime.Core.Models;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
|
||||
namespace FileTime.ConsoleUI.App;
|
||||
|
||||
public class RootViewModel : IRootViewModel
|
||||
public partial class RootViewModel : IRootViewModel
|
||||
{
|
||||
public string UserName => Environment.UserName;
|
||||
public string MachineName => Environment.MachineName;
|
||||
@@ -19,6 +21,7 @@ public class RootViewModel : IRootViewModel
|
||||
public ICommandPaletteViewModel CommandPalette { get; }
|
||||
public IFrequencyNavigationViewModel FrequencyNavigation { get; }
|
||||
public IItemPreviewService ItemPreviewService { get; }
|
||||
public IClipboardService ClipboardService { get; }
|
||||
public IDialogService DialogService { get; }
|
||||
public ITimelineViewModel TimelineViewModel { get; }
|
||||
public IDeclarativeProperty<VolumeSizeInfo?> VolumeSizeInfo { get;}
|
||||
@@ -32,7 +35,8 @@ public class RootViewModel : IRootViewModel
|
||||
IDialogService dialogService,
|
||||
ITimelineViewModel timelineViewModel,
|
||||
IFrequencyNavigationViewModel frequencyNavigation,
|
||||
IItemPreviewService itemPreviewService)
|
||||
IItemPreviewService itemPreviewService,
|
||||
IClipboardService clipboardService)
|
||||
{
|
||||
AppState = appState;
|
||||
PossibleCommands = possibleCommands;
|
||||
@@ -41,6 +45,7 @@ public class RootViewModel : IRootViewModel
|
||||
TimelineViewModel = timelineViewModel;
|
||||
FrequencyNavigation = frequencyNavigation;
|
||||
ItemPreviewService = itemPreviewService;
|
||||
ClipboardService = clipboardService;
|
||||
|
||||
DialogService.ReadInput.PropertyChanged += (o, e) =>
|
||||
{
|
||||
@@ -53,6 +58,14 @@ public class RootViewModel : IRootViewModel
|
||||
}
|
||||
};
|
||||
|
||||
itemPreviewService.ItemPreview.PropertyChanged += (o, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(itemPreviewService.ItemPreview.Value))
|
||||
{
|
||||
appState.PreviewType = null;
|
||||
}
|
||||
};
|
||||
|
||||
VolumeSizeInfo = appState.SelectedTab
|
||||
.Map(t => t?.CurrentLocation)
|
||||
.Switch()
|
||||
|
||||
@@ -5,6 +5,7 @@ using FileTime.ConsoleUI.App.Configuration;
|
||||
using FileTime.ConsoleUI.App.Controls;
|
||||
using FileTime.ConsoleUI.App.KeyInputHandling;
|
||||
using FileTime.ConsoleUI.App.Services;
|
||||
using FileTime.ConsoleUI.App.UserCommand;
|
||||
using FileTime.Core.Interactions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -12,6 +13,16 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace FileTime.ConsoleUI.App;
|
||||
|
||||
public class StartupHandler : IStartupHandler
|
||||
{
|
||||
public StartupHandler(IIdentifiableUserCommandService identifiableUserCommandService)
|
||||
{
|
||||
identifiableUserCommandService.AddIdentifiableUserCommand(NextPreviewUserCommand.Instance);
|
||||
identifiableUserCommandService.AddIdentifiableUserCommand(PreviousPreviewUserCommand.Instance);
|
||||
}
|
||||
public Task InitAsync() => Task.CompletedTask;
|
||||
}
|
||||
|
||||
public static class Startup
|
||||
{
|
||||
public static IServiceCollection AddConsoleServices(this IServiceCollection services, IConfigurationRoot configuration)
|
||||
@@ -27,6 +38,8 @@ public static class Startup
|
||||
services.TryAddSingleton<IRootViewModel, RootViewModel>();
|
||||
services.TryAddSingleton<IDialogService, DialogService>();
|
||||
services.TryAddSingleton<IUserCommunicationService>(sp => sp.GetRequiredService<IDialogService>());
|
||||
services.AddSingleton<IUserCommandHandler, ConsoleUserCommandHandler>();
|
||||
services.AddSingleton<IStartupHandler, StartupHandler>();
|
||||
|
||||
services.Configure<ConsoleApplicationConfiguration>(configuration);
|
||||
return services;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.Services.UserCommandHandler;
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
using FileTime.ConsoleUI.App.Preview;
|
||||
|
||||
namespace FileTime.ConsoleUI.App.UserCommand;
|
||||
|
||||
public class ConsoleUserCommandHandler : AggregatedUserCommandHandler
|
||||
{
|
||||
private static readonly ItemPreviewType[] ElementPreviewOrder = {ItemPreviewType.Text, ItemPreviewType.Binary};
|
||||
|
||||
private readonly IConsoleAppState _consoleAppState;
|
||||
private readonly IItemPreviewService _itemPreviewService;
|
||||
|
||||
public ConsoleUserCommandHandler(
|
||||
IConsoleAppState consoleAppState,
|
||||
IItemPreviewService itemPreviewService
|
||||
)
|
||||
{
|
||||
_consoleAppState = consoleAppState;
|
||||
_itemPreviewService = itemPreviewService;
|
||||
AddCommandHandler(new IUserCommandHandler[]
|
||||
{
|
||||
new TypeUserCommandHandler<NextPreviewUserCommand>(NextPreview),
|
||||
new TypeUserCommandHandler<PreviousPreviewUserCommand>(PreviousPreview),
|
||||
});
|
||||
}
|
||||
|
||||
private Task NextPreview()
|
||||
{
|
||||
if (_itemPreviewService.ItemPreview.Value is not IElementPreviewViewModel) return Task.CompletedTask;
|
||||
|
||||
var previewOrder = ElementPreviewOrder;
|
||||
if (previewOrder.Length < 2) return Task.CompletedTask;
|
||||
|
||||
if (_consoleAppState.PreviewType == null)
|
||||
{
|
||||
_consoleAppState.PreviewType = previewOrder.Length > 1 ? previewOrder[1] : null;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var currentPreviewType = _consoleAppState.PreviewType.Value;
|
||||
int i;
|
||||
for (i = 0; i < previewOrder.Length; i++)
|
||||
{
|
||||
if (previewOrder[i] == currentPreviewType) break;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
_consoleAppState.PreviewType = i >= previewOrder.Length ? previewOrder[0] : previewOrder[i];
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task PreviousPreview()
|
||||
{
|
||||
if (_itemPreviewService.ItemPreview.Value is not IElementPreviewViewModel) return Task.CompletedTask;
|
||||
|
||||
var previewOrder = ElementPreviewOrder;
|
||||
if (previewOrder.Length < 2) return Task.CompletedTask;
|
||||
|
||||
if (_consoleAppState.PreviewType == null)
|
||||
{
|
||||
_consoleAppState.PreviewType = previewOrder.Length > 1 ? previewOrder[^1] : null;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
var currentPreviewType = _consoleAppState.PreviewType.Value;
|
||||
int i;
|
||||
for (i = previewOrder.Length - 1; i > -1; i--)
|
||||
{
|
||||
if (previewOrder[i] == currentPreviewType) break;
|
||||
}
|
||||
|
||||
i--;
|
||||
|
||||
_consoleAppState.PreviewType = i > -1 ? previewOrder[^1] : previewOrder[i];
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user