improved the context menu

This commit is contained in:
2025-03-13 06:19:04 +01:00
parent 249e74eb7b
commit 07912b3239
2 changed files with 292 additions and 237 deletions

View File

@@ -9,7 +9,6 @@ using System.Reflection;
using System.Threading.Tasks;
using K8sFileBrowser.Models;
using K8sFileBrowser.Services;
using Microsoft.IdentityModel.Tokens;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Serilog;
@@ -66,13 +65,10 @@ public class MainWindowViewModel : ViewModelBase
#region Commands
public ReactiveCommand<Unit, Unit> DownloadCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> DownloadLogCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> RefreshCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> ParentCommand { get; private set; } = null!;
public ReactiveCommand<Unit, Unit> OpenCommand { get; private set; } = null!;
public ReactiveCommand<FileInformation, Unit> OpenContextCommand { get; private set; } = null!;
public ReactiveCommand<FileInformation, Unit> DownloadContextCommand { get; private set; } = null!;
private ReactiveCommand<Namespace, IEnumerable<Pod>> GetPodsForNamespace { get; set; } = null!;
@@ -85,9 +81,7 @@ public class MainWindowViewModel : ViewModelBase
Version = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
// commands
ConfigureOpenDirectoryCommand();
ConfigureOpenDirectoryContextCommand();
ConfigureDownloadFileCommand(kubernetesService);
ConfigureDownloadFileContextCommand(kubernetesService);
ConfigureRefreshCommand(kubernetesService);
ConfigureDownloadLogCommand(kubernetesService);
@@ -275,32 +269,7 @@ public class MainWindowViewModel : ViewModelBase
.Subscribe(ShowErrorMessage);
}
private void ConfigureDownloadFileCommand(IKubernetesService kubernetesService)
{
var isFile = this
.WhenAnyValue(x => x.SelectedFile, x => x.Message.IsVisible)
.Select(x => x is { Item1.Type: FileType.File, Item2: false });
DownloadCommand = ReactiveCommand.CreateFromTask(async () =>
{
await Observable.StartAsync(async () =>
{
var fileName = SelectedFile!.Name.Substring(SelectedFile!.Name.LastIndexOf('/') + 1,
SelectedFile!.Name.Length - SelectedFile!.Name.LastIndexOf('/') - 1);
var saveFileName = await ApplicationHelper.SaveFile(_lastDirectory, fileName);
if (saveFileName != null)
{
SetLastDirectory(saveFileName);
ShowWorkingMessage("Downloading File...");
await kubernetesService.DownloadFile(SelectedNamespace, SelectedPod, SelectedContainer, SelectedFile, saveFileName);
HideWorkingMessage();
}
}, RxApp.TaskpoolScheduler);
}, isFile, RxApp.MainThreadScheduler);
DownloadCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ShowErrorMessage);
}
private void ConfigureDownloadFileContextCommand(IKubernetesService kubernetesService)
{
@@ -322,7 +291,7 @@ public class MainWindowViewModel : ViewModelBase
}, RxApp.TaskpoolScheduler);
}, outputScheduler: RxApp.MainThreadScheduler);
DownloadCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
DownloadContextCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ShowErrorMessage);
}
@@ -331,24 +300,6 @@ public class MainWindowViewModel : ViewModelBase
_lastDirectory = saveFileName.Substring(0, saveFileName.LastIndexOf(Path.DirectorySeparatorChar));
}
private void ConfigureOpenDirectoryCommand()
{
var isDirectory = this
.WhenAnyValue(x => x.SelectedFile, x => x.Message.IsVisible)
.Select(x => x is { Item1.Type: FileType.Directory, Item2: false });
OpenCommand = ReactiveCommand.Create(() =>
{
if (".." == SelectedFile?.Name)
SelectedPath = SelectedFile?.Parent;
else
SelectedPath = SelectedFile != null ? SelectedFile!.Name : "/";
},
isDirectory, RxApp.MainThreadScheduler);
OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ShowErrorMessage);
}
private void ConfigureOpenDirectoryContextCommand()
{
@@ -357,7 +308,7 @@ public class MainWindowViewModel : ViewModelBase
SelectedPath = ".." == file.Name ? file.Parent : file.Name;
}, outputScheduler: RxApp.MainThreadScheduler);
OpenCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
OpenContextCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(ShowErrorMessage);
}

View File

@@ -15,10 +15,15 @@
</Design.DataContext>
<Grid>
<Border ZIndex="1" IsVisible="{Binding Message.IsVisible}" Background="{Binding Message.Color}" Opacity="{Binding Message.Opacity}">
<Border ZIndex="1" IsVisible="{Binding Message.IsVisible}" Background="{Binding Message.Color}"
Opacity="{Binding Message.Opacity}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Spacing="20" MaxWidth="500">
<PathIcon Classes="loading" Data="{StaticResource arrow_rotate_clockwise_regular}" Width="100" Height="100" IsVisible="{Binding !Message.IsError}"></PathIcon>
<PathIcon Data="{StaticResource warning_regular}" Width="100" Height="100" IsVisible="{Binding Message.IsError}"></PathIcon>
<PathIcon Classes="loading" Data="{StaticResource arrow_rotate_clockwise_regular}" Width="100"
Height="100" IsVisible="{Binding !Message.IsError}">
</PathIcon>
<PathIcon Data="{StaticResource warning_regular}" Width="100" Height="100"
IsVisible="{Binding Message.IsError}">
</PathIcon>
<TextBlock TextWrapping="Wrap" Text="{Binding Message.Text}">.</TextBlock>
</StackPanel>
</Border>
@@ -49,7 +54,8 @@
MinWidth="200"
Margin="0 0 10 0">
</ComboBox>
<TextBlock Grid.Column="4" HorizontalAlignment="Right" VerticalAlignment="Center" Text="{Binding Version}"/>
<TextBlock Grid.Column="4" HorizontalAlignment="Right" VerticalAlignment="Center"
Text="{Binding Version}" />
</Grid>
</Border>
@@ -90,20 +96,28 @@
Margin="0 0 10 0">
</ComboBox>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="4" Margin="10" HorizontalAlignment="Right">
<Button Command="{Binding DownloadLogCommand}" VerticalAlignment="Center" ToolTip.Tip="Download Container Log" Margin="0 0 48 0 ">
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="4" Margin="10"
HorizontalAlignment="Right">
<Button Command="{Binding DownloadLogCommand}" VerticalAlignment="Center"
ToolTip.Tip="Download Container Log" Margin="0 0 48 0 ">
<PathIcon Data="{StaticResource document_one_page_regular}"></PathIcon>
</Button>
<Button Command="{Binding RefreshCommand}" VerticalAlignment="Center" ToolTip.Tip="Refresh Directory">
<Button Command="{Binding RefreshCommand}" VerticalAlignment="Center"
ToolTip.Tip="Refresh Directory">
<PathIcon Data="{StaticResource arrow_sync_circle_regular}"></PathIcon>
</Button>
<Button Command="{Binding ParentCommand}" VerticalAlignment="Center" ToolTip.Tip="Go To Parent Directory">
<Button Command="{Binding ParentCommand}" VerticalAlignment="Center"
ToolTip.Tip="Go To Parent Directory">
<PathIcon Data="{StaticResource arrow_curve_up_left_regular}"></PathIcon>
</Button>
<Button Command="{Binding OpenCommand}" VerticalAlignment="Center" ToolTip.Tip="Browse Directory">
<Button Command="{Binding OpenContextCommand}" CommandParameter="{Binding SelectedFile}"
IsEnabled="{Binding SelectedFile.IsDirectory}" VerticalAlignment="Center"
ToolTip.Tip="Browse Directory">
<PathIcon Data="{StaticResource arrow_right_regular}"></PathIcon>
</Button>
<Button Command="{Binding DownloadCommand}" VerticalAlignment="Center" ToolTip.Tip="Download File">
<Button Command="{Binding DownloadContextCommand}"
CommandParameter="{Binding SelectedFile}" IsEnabled="{Binding SelectedFile.IsFile}"
VerticalAlignment="Center" ToolTip.Tip="Download File">
<PathIcon Data="{StaticResource arrow_download_regular}"></PathIcon>
</Button>
</StackPanel>
@@ -132,15 +146,46 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="models:FileInformation">
<Border ToolTip.Tip="{Binding Type}" Background="Transparent">
<Border.ContextFlyout>
<MenuFlyout>
<MenuItem Header="Open"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_right_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Download"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).DownloadContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsFile}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_download_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
</MenuFlyout>
</Border.ContextFlyout>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<PathIcon Data="{StaticResource folder_regular}" IsVisible="{Binding IsDirectory}"></PathIcon>
<PathIcon Data="{StaticResource document_regular}" IsVisible="{Binding IsFile}"></PathIcon>
<PathIcon Data="{StaticResource document_error_regular}" IsVisible="{Binding IsSymbolicLink}"></PathIcon>
<PathIcon Data="{StaticResource document_unknown_regular}" IsVisible="{Binding IsUnknown}"></PathIcon>
<PathIcon Data="{StaticResource folder_regular}"
IsVisible="{Binding IsDirectory}">
</PathIcon>
<PathIcon Data="{StaticResource document_regular}"
IsVisible="{Binding IsFile}">
</PathIcon>
<PathIcon Data="{StaticResource document_error_regular}"
IsVisible="{Binding IsSymbolicLink}">
</PathIcon>
<PathIcon Data="{StaticResource document_unknown_regular}"
IsVisible="{Binding IsUnknown}">
</PathIcon>
</StackPanel>
<Interaction.Behaviors>
<EventTriggerBehavior EventName="DoubleTapped">
<InvokeCommandAction Command="{Binding ((vm:MainWindowViewModel)DataContext).OpenCommand, RelativeSource={RelativeSource AncestorType=Window }}" />
<InvokeCommandAction
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}"/>
</EventTriggerBehavior>
</Interaction.Behaviors>
</Border>
@@ -156,17 +201,28 @@
<MenuItem Header="Open"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}"/>
IsEnabled="{Binding IsDirectory}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_right_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Download"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).DownloadContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsFile}"/>
IsEnabled="{Binding IsFile}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_download_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
</MenuFlyout>
</Border.ContextFlyout>
<TextBlock Text="{Binding DisplayName}" VerticalAlignment="Center" />
<Interaction.Behaviors>
<EventTriggerBehavior EventName="DoubleTapped">
<InvokeCommandAction Command="{Binding ((vm:MainWindowViewModel)DataContext).OpenCommand, RelativeSource={RelativeSource AncestorType=Window }}" />
<InvokeCommandAction
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}"/>
</EventTriggerBehavior>
</Interaction.Behaviors>
</Border>
@@ -177,10 +233,34 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="models:FileInformation">
<Border Background="Transparent">
<TextBlock Text="{Binding Size}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 0 10 0"/>
<Border.ContextFlyout>
<MenuFlyout>
<MenuItem Header="Open"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_right_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Download"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).DownloadContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsFile}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_download_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
</MenuFlyout>
</Border.ContextFlyout>
<TextBlock Text="{Binding Size}" VerticalAlignment="Center"
HorizontalAlignment="Right" Margin="0 0 10 0" />
<Interaction.Behaviors>
<EventTriggerBehavior EventName="DoubleTapped">
<InvokeCommandAction Command="{Binding ((vm:MainWindowViewModel)DataContext).OpenCommand, RelativeSource={RelativeSource AncestorType=Window }}" />
<InvokeCommandAction
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}"/>
</EventTriggerBehavior>
</Interaction.Behaviors>
</Border>
@@ -191,10 +271,34 @@
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="models:FileInformation">
<Border Background="Transparent">
<TextBlock Text="{Binding DateTimeOffsetString}" VerticalAlignment="Center" Margin="10 0 8 0"/>
<Border.ContextFlyout>
<MenuFlyout>
<MenuItem Header="Open"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_right_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Download"
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).DownloadContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsFile}">
<MenuItem.Icon>
<PathIcon Data="{StaticResource arrow_download_regular}"></PathIcon>
</MenuItem.Icon>
</MenuItem>
</MenuFlyout>
</Border.ContextFlyout>
<TextBlock Text="{Binding DateTimeOffsetString}" VerticalAlignment="Center"
Margin="10 0 8 0" />
<Interaction.Behaviors>
<EventTriggerBehavior EventName="DoubleTapped">
<InvokeCommandAction Command="{Binding ((vm:MainWindowViewModel)DataContext).OpenCommand, RelativeSource={RelativeSource AncestorType=Window}}" />
<InvokeCommandAction
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).OpenContextCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding IsDirectory}"/>
</EventTriggerBehavior>
</Interaction.Behaviors>
</Border>