Console MessageBox, admin mode
This commit is contained in:
@@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using TerminalUI;
|
||||
using TerminalUI.ConsoleDrivers;
|
||||
using TerminalUI.Models;
|
||||
|
||||
namespace FileTime.ConsoleUI.App;
|
||||
|
||||
@@ -138,6 +139,14 @@ public class App : IApplication
|
||||
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
|
||||
_consoleDriver.ExitRestrictedMode();
|
||||
_consoleDriver.Clear();
|
||||
var size = _consoleDriver.GetWindowSize();
|
||||
var shutdownText = "Shutting down...";
|
||||
|
||||
_consoleDriver.SetCursorPosition(new Position(size.Width / 2 - shutdownText.Length / 2, size.Height / 2));
|
||||
_consoleDriver.Write(shutdownText);
|
||||
|
||||
Task.Run(async () => await _lifecycleService.ExitAsync()).Wait();
|
||||
}
|
||||
|
||||
@@ -51,35 +51,96 @@ public class Dialogs
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateReadInputsFocus()
|
||||
public IView<IRootViewModel> View()
|
||||
{
|
||||
foreach (var readInputsChild in _readInputs.Children)
|
||||
var root = new Grid<IRootViewModel>()
|
||||
{
|
||||
if (readInputsChild.DataContext == _inputElementToFocus)
|
||||
Margin = 5,
|
||||
ChildInitializer =
|
||||
{
|
||||
if (FindFocusable(readInputsChild) is { } focusable)
|
||||
{
|
||||
focusable.Focus();
|
||||
_inputElementToFocus = null;
|
||||
break;
|
||||
}
|
||||
ReadInputs(),
|
||||
MessageBox()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
IFocusable? FindFocusable(IView view)
|
||||
{
|
||||
if (view is IFocusable focusable) return focusable;
|
||||
foreach (var viewVisualChild in view.VisualChildren)
|
||||
{
|
||||
if (FindFocusable(viewVisualChild) is { } focusableChild)
|
||||
return focusableChild;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
public IView<IRootViewModel> View()
|
||||
private IView<IRootViewModel> MessageBox()
|
||||
{
|
||||
var okButton = new Button<IRootViewModel>
|
||||
{
|
||||
Margin = "0 0 5 0",
|
||||
Content = new TextBlock<IRootViewModel>()
|
||||
.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.DialogService.LastMessageBox.Value.OkText,
|
||||
t => t.Text)),
|
||||
}.WithClickHandler(b => b.DataContext?.DialogService.LastMessageBox.Value?.Ok());
|
||||
|
||||
var cancelButton =
|
||||
new Button<IRootViewModel>
|
||||
{
|
||||
Margin = "0 0 5 0",
|
||||
Content = new TextBlock<IRootViewModel>()
|
||||
.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.DialogService.LastMessageBox.Value.CancelText,
|
||||
t => t.Text)),
|
||||
}
|
||||
.Setup(b => b.Bind(
|
||||
b,
|
||||
dc => dc.DialogService.LastMessageBox.Value.ShowCancel,
|
||||
b => b.IsVisible))
|
||||
.WithClickHandler(b => b.DataContext?.DialogService.LastMessageBox.Value?.Cancel());
|
||||
|
||||
var root = new Border<IRootViewModel>
|
||||
{
|
||||
Margin = 5,
|
||||
BorderThickness = 1,
|
||||
Background = SpecialColor.None,
|
||||
Content = new Grid<IRootViewModel>
|
||||
{
|
||||
RowDefinitionsObject = "Auto Auto",
|
||||
ChildInitializer =
|
||||
{
|
||||
new TextBlock<IRootViewModel>()
|
||||
.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.DialogService.LastMessageBox.Value.Text,
|
||||
t => t.Text)),
|
||||
new StackPanel<IRootViewModel>
|
||||
{
|
||||
Orientation = Orientation.Horizontal,
|
||||
Extensions = {new GridPositionExtension(0, 1)},
|
||||
ChildInitializer =
|
||||
{
|
||||
okButton,
|
||||
cancelButton
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
root.Bind(
|
||||
root,
|
||||
d => d.DialogService.LastMessageBox.Value != null,
|
||||
v => v.IsVisible,
|
||||
fallbackValue: false);
|
||||
|
||||
((INotifyPropertyChanged) root).PropertyChanged += (_, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(IView.IsVisible))
|
||||
{
|
||||
okButton.Focus();
|
||||
}
|
||||
};
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private IView<IRootViewModel> ReadInputs()
|
||||
{
|
||||
var root = new Border<IRootViewModel>
|
||||
{
|
||||
@@ -88,9 +149,20 @@ public class Dialogs
|
||||
Background = SpecialColor.None,
|
||||
Content = new Grid<IRootViewModel>
|
||||
{
|
||||
RowDefinitionsObject = "Auto Auto",
|
||||
ChildInitializer =
|
||||
{
|
||||
ReadInputs()
|
||||
ReadInputsList(),
|
||||
new ItemsControl<IRootViewModel, IPreviewElement>
|
||||
{
|
||||
ItemTemplate = ReadInputPreviewItemTemplate
|
||||
}
|
||||
.Setup(i => i.Bind(
|
||||
i,
|
||||
dc => dc.DialogService.ReadInput.Value.Previews,
|
||||
c => c.ItemsSource
|
||||
))
|
||||
.WithExtension(new GridPositionExtension(0, 1))
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -100,58 +172,9 @@ public class Dialogs
|
||||
d => d.DialogService.ReadInput.Value != null,
|
||||
v => v.IsVisible);
|
||||
|
||||
((INotifyPropertyChanged) _readInputs).PropertyChanged += (_, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(ItemsControl<object, object>.Children))
|
||||
{
|
||||
_readInputChildHandlerUnSubscriber?.Invoke();
|
||||
|
||||
if (_readInputs.Children.Count > 0)
|
||||
{
|
||||
UpdateReadInputsFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
_inputElementToFocus = null;
|
||||
}
|
||||
|
||||
if (_readInputs.Children is INotifyCollectionChanged notifyCollectionChanged)
|
||||
{
|
||||
notifyCollectionChanged.CollectionChanged += NotifyCollectionChangedEventHandler;
|
||||
_readInputChildHandlerUnSubscriber = () => { notifyCollectionChanged.CollectionChanged -= NotifyCollectionChangedEventHandler; };
|
||||
}
|
||||
|
||||
void NotifyCollectionChangedEventHandler(
|
||||
object? sender,
|
||||
NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateReadInputsFocus();
|
||||
}
|
||||
}
|
||||
};
|
||||
return root;
|
||||
}
|
||||
|
||||
private IView<IRootViewModel> ReadInputs()
|
||||
=> new Grid<IRootViewModel>
|
||||
{
|
||||
RowDefinitionsObject = "Auto Auto",
|
||||
ChildInitializer =
|
||||
{
|
||||
ReadInputsList(),
|
||||
new ItemsControl<IRootViewModel, IPreviewElement>
|
||||
{
|
||||
ItemTemplate = ReadInputPreviewItemTemplate
|
||||
}
|
||||
.Setup(i => i.Bind(
|
||||
i,
|
||||
dc => dc.DialogService.ReadInput.Value.Previews,
|
||||
c => c.ItemsSource
|
||||
))
|
||||
.WithExtension(new GridPositionExtension(0, 1))
|
||||
}
|
||||
};
|
||||
|
||||
private IView<IPreviewElement> ReadInputPreviewItemTemplate()
|
||||
{
|
||||
var grid = new Grid<IPreviewElement>
|
||||
@@ -367,6 +390,64 @@ public class Dialogs
|
||||
|
||||
_readInputs = readInputs;
|
||||
|
||||
((INotifyPropertyChanged) _readInputs).PropertyChanged += (_, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(ItemsControl<object, object>.Children))
|
||||
{
|
||||
_readInputChildHandlerUnSubscriber?.Invoke();
|
||||
|
||||
if (_readInputs.Children.Count > 0)
|
||||
{
|
||||
UpdateReadInputsFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
_inputElementToFocus = null;
|
||||
}
|
||||
|
||||
if (_readInputs.Children is INotifyCollectionChanged notifyCollectionChanged)
|
||||
{
|
||||
notifyCollectionChanged.CollectionChanged += NotifyCollectionChangedEventHandler;
|
||||
_readInputChildHandlerUnSubscriber = () => { notifyCollectionChanged.CollectionChanged -= NotifyCollectionChangedEventHandler; };
|
||||
}
|
||||
|
||||
void NotifyCollectionChangedEventHandler(
|
||||
object? sender,
|
||||
NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateReadInputsFocus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return readInputs;
|
||||
}
|
||||
|
||||
private void UpdateReadInputsFocus()
|
||||
{
|
||||
foreach (var readInputsChild in _readInputs.Children)
|
||||
{
|
||||
if (readInputsChild.DataContext == _inputElementToFocus)
|
||||
{
|
||||
if (FindFocusable(readInputsChild) is { } focusable)
|
||||
{
|
||||
focusable.Focus();
|
||||
_inputElementToFocus = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IFocusable? FindFocusable(IView view)
|
||||
{
|
||||
if (view is IFocusable focusable) return focusable;
|
||||
foreach (var viewVisualChild in view.VisualChildren)
|
||||
{
|
||||
if (FindFocusable(viewVisualChild) is { } focusableChild)
|
||||
return focusableChild;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,12 +138,22 @@ public class MainWindow
|
||||
{
|
||||
Margin = "2 0 0 0",
|
||||
Extensions = {new GridPositionExtension(2, 0)},
|
||||
Orientation = Orientation.Horizontal,
|
||||
ChildInitializer =
|
||||
{
|
||||
new TextBlock<IRootViewModel>
|
||||
{
|
||||
Text = _consoleApplicationConfiguration.Value.AdminModeIcon ??
|
||||
(_consoleApplicationConfiguration.Value.DisableUtf8 ? "A+ " : "\ud83d\udd11"),
|
||||
AsciiOnly = false
|
||||
}.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.AdminElevationManager.IsAdminInstanceRunning,
|
||||
t => t.IsVisible)),
|
||||
new TextBlock<IRootViewModel>
|
||||
{
|
||||
Text = _consoleApplicationConfiguration.Value.ClipboardSingleIcon ??
|
||||
(_consoleApplicationConfiguration.Value.DisableUtf8 ? "C" : "\ud83d\udccb"),
|
||||
(_consoleApplicationConfiguration.Value.DisableUtf8 ? "C " : "\ud83d\udccb"),
|
||||
AsciiOnly = false
|
||||
}.Setup(t => t.Bind(
|
||||
t,
|
||||
@@ -152,7 +162,7 @@ public class MainWindow
|
||||
new TextBlock<IRootViewModel>
|
||||
{
|
||||
Text = _consoleApplicationConfiguration.Value.ClipboardMultipleIcon ??
|
||||
(_consoleApplicationConfiguration.Value.DisableUtf8 ? "CC" : "\ud83d\udccb+"),
|
||||
(_consoleApplicationConfiguration.Value.DisableUtf8 ? "CC " : "\ud83d\udccb+"),
|
||||
AsciiOnly = false
|
||||
}.Setup(t => t.Bind(
|
||||
t,
|
||||
|
||||
@@ -7,6 +7,7 @@ using FileTime.App.FrequencyNavigation.ViewModels;
|
||||
using FileTime.ConsoleUI.App.Services;
|
||||
using FileTime.Core.Interactions;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Providers.LocalAdmin;
|
||||
|
||||
namespace FileTime.ConsoleUI.App;
|
||||
|
||||
@@ -20,6 +21,7 @@ public partial class RootViewModel : IRootViewModel
|
||||
public IFrequencyNavigationViewModel FrequencyNavigation { get; }
|
||||
public IItemPreviewService ItemPreviewService { get; }
|
||||
public IClipboardService ClipboardService { get; }
|
||||
public IAdminElevationManager AdminElevationManager { get; }
|
||||
public IDialogService DialogService { get; }
|
||||
public ITimelineViewModel TimelineViewModel { get; }
|
||||
public IDeclarativeProperty<VolumeSizeInfo?> VolumeSizeInfo { get;}
|
||||
@@ -34,7 +36,8 @@ public partial class RootViewModel : IRootViewModel
|
||||
ITimelineViewModel timelineViewModel,
|
||||
IFrequencyNavigationViewModel frequencyNavigation,
|
||||
IItemPreviewService itemPreviewService,
|
||||
IClipboardService clipboardService)
|
||||
IClipboardService clipboardService,
|
||||
IAdminElevationManager adminElevationManager)
|
||||
{
|
||||
AppState = appState;
|
||||
PossibleCommands = possibleCommands;
|
||||
@@ -44,6 +47,7 @@ public partial class RootViewModel : IRootViewModel
|
||||
FrequencyNavigation = frequencyNavigation;
|
||||
ItemPreviewService = itemPreviewService;
|
||||
ClipboardService = clipboardService;
|
||||
AdminElevationManager = adminElevationManager;
|
||||
|
||||
DialogService.ReadInput.PropertyChanged += (o, e) =>
|
||||
{
|
||||
|
||||
@@ -8,21 +8,27 @@ namespace FileTime.ConsoleUI.App.Services;
|
||||
public class CustomLoggerSink : ILogEventSink
|
||||
{
|
||||
private readonly Lazy<IDialogService> _dialogService;
|
||||
|
||||
|
||||
public CustomLoggerSink(IServiceProvider serviceProvider)
|
||||
{
|
||||
_dialogService = new Lazy<IDialogService>(() => serviceProvider.GetRequiredService<IDialogService>());
|
||||
}
|
||||
|
||||
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
if (logEvent.Level >= LogEventLevel.Error)
|
||||
if (logEvent.Level >= LogEventLevel.Error
|
||||
&& logEvent.Properties.TryGetValue("SourceContext", out var sourceContext))
|
||||
{
|
||||
var message = logEvent.RenderMessage();
|
||||
if (logEvent.Exception is not null)
|
||||
message += $" {logEvent.Exception.Message}";
|
||||
Debug.WriteLine(message);
|
||||
_dialogService.Value.ShowToastMessage(message);
|
||||
var s = sourceContext.ToString();
|
||||
|
||||
if (s != "\"Microsoft.AspNetCore.SignalR.Client.HubConnection\"")
|
||||
{
|
||||
var message = logEvent.RenderMessage();
|
||||
if (logEvent.Exception is not null)
|
||||
message += $" {logEvent.Exception.Message}";
|
||||
Debug.WriteLine(message);
|
||||
_dialogService.Value.ShowToastMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user