about summary refs log tree commit diff
path: root/ModerationClient/Views/UserManagementWindow.axaml
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-08-08 02:57:34 +0200
committerRory& <root@rory.gay>2024-08-08 03:02:10 +0200
commitdf5fe7c86e41235f99a9b0d69519a18581eddd5e (patch)
treed7ae3b2c9b98ffcf4fbe4613091dfc7db7e2c62b /ModerationClient/Views/UserManagementWindow.axaml
parentList rooms (diff)
downloadModerationClient-df5fe7c86e41235f99a9b0d69519a18581eddd5e.tar.xz
Further work
Diffstat (limited to '')
-rw-r--r--ModerationClient/Views/UserManagementWindow.axaml59
-rw-r--r--ModerationClient/Views/UserManagementWindow.axaml.cs136
2 files changed, 195 insertions, 0 deletions
diff --git a/ModerationClient/Views/UserManagementWindow.axaml b/ModerationClient/Views/UserManagementWindow.axaml
new file mode 100644

index 0000000..ef93517 --- /dev/null +++ b/ModerationClient/Views/UserManagementWindow.axaml
@@ -0,0 +1,59 @@ +<Window xmlns="https://github.com/avaloniaui" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:vm="using:ModerationClient.ViewModels" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:views="clr-namespace:ModerationClient.Views" + xmlns:responses="clr-namespace:LibMatrix.Homeservers.ImplementationDetails.Synapse.Models.Responses;assembly=LibMatrix" + mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + x:Class="ModerationClient.Views.UserManagementWindow" + x:DataType="vm:MainWindowViewModel" + Icon="/Assets/avalonia-logo.ico" + Title="ModerationClient" + Width="640" Height="480"> + <!-- <Design.DataContext> --> + <!-- This only sets the DataContext for the previewer in an IDE, + to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) --> + <!-- <vm:MainWindowViewModel /> --> + <!-- </Design.DataContext> --> + + <Grid RowDefinitions="Auto, *"> + <Grid Grid.Row="0" ColumnDefinitions="Auto, *, Auto" x:Name="TopPanel"> + <StackPanel Orientation="Horizontal" Grid.Column="0"> + <Label Content="{CompiledBinding Scale}" /> + <Label>x</Label> + <Rectangle Width="32" /> + <Label Content="{CompiledBinding ChildTargetWidth}" /> + <Label>x</Label> + <Label Content="{CompiledBinding ChildTargetHeight}" /> + </StackPanel> + <Label Grid.Column="2">Press '?' for keybinds</Label> + </Grid> + <Viewbox Grid.Row="1"> + <ScrollViewer + Width="{CompiledBinding ChildTargetWidth}" + Background="#222222" + Height="{CompiledBinding ChildTargetHeight}"> + <ContentControl DataContext="{CompiledBinding Path=CurrentViewModel}"> + <ItemsControl ItemsSource="{ReflectionBinding Users}"> + <ItemsControl.ItemTemplate> + <DataTemplate DataType="vm:User"> + <StackPanel Orientation="Vertical"> + <StackPanel Orientation="Horizontal"> + <TextBlock Text="{CompiledBinding Name}" /> + <TextBlock Text="{CompiledBinding DisplayName}" /> + </StackPanel> + <StackPanel Orientation="Horizontal"> + <Button Tag="{CompiledBinding .}" Click="PuppetButtonClicked">Puppet</Button> + <!-- <Button>Terminate</Button> --> + </StackPanel> + </StackPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </ContentControl> + </ScrollViewer> + </Viewbox> + </Grid> + +</Window> \ No newline at end of file diff --git a/ModerationClient/Views/UserManagementWindow.axaml.cs b/ModerationClient/Views/UserManagementWindow.axaml.cs new file mode 100644
index 0000000..2d2dfb4 --- /dev/null +++ b/ModerationClient/Views/UserManagementWindow.axaml.cs
@@ -0,0 +1,136 @@ +using System; +using ArcaneLibs.Extensions; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Diagnostics; +using Avalonia.Input; +using Avalonia.Interactivity; +using LibMatrix.Homeservers; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ModerationClient.Services; +using ModerationClient.ViewModels; + +namespace ModerationClient.Views; + +public partial class UserManagementWindow : Window { + private readonly CommandLineConfiguration _cfg; + private readonly MatrixAuthenticationService _auth; + + public UserManagementWindow(CommandLineConfiguration cfg, MainWindowViewModel dataContext, IHostApplicationLifetime appLifetime, + UserManagementViewModel userManagementViewModel, MatrixAuthenticationService auth) { + _cfg = cfg; + _auth = auth; + InitializeComponent(); + DataContext = dataContext; + dataContext.CurrentViewModel = userManagementViewModel; + Console.WriteLine("mainwnd"); +#if DEBUG + this.AttachDevTools(new DevToolsOptions() { + ShowAsChildWindow = true, + LaunchView = DevToolsViewKind.LogicalTree, + }); +#endif + PropertyChanged += (sender, args) => { + // Console.WriteLine($"MainWindow PropertyChanged: {args.Property.Name} ({args.OldValue} -> {args.NewValue})"); + switch (args.Property.Name) { + case nameof(ClientSize): { + if (DataContext is not MainWindowViewModel viewModel) { + Console.WriteLine("WARN: MainWindowViewModel is null, ignoring ClientSize change!"); + return; + } + + viewModel.PhysicalSize = new Size(ClientSize.Width, ClientSize.Height - TopPanel.Bounds.Height); + break; + } + } + }; + + TopPanel.PropertyChanged += (_, args) => { + if (args.Property.Name == nameof(TopPanel.Bounds)) { + if (DataContext is not MainWindowViewModel viewModel) { + Console.WriteLine("WARN: MainWindowViewModel is null, ignoring TopPanel.Bounds change!"); + return; + } + + viewModel.PhysicalSize = new Size(ClientSize.Width, ClientSize.Height - TopPanel.Bounds.Height); + } + }; + + dataContext.AuthService.PropertyChanged += (sender, args) => { + if (args.PropertyName == nameof(MatrixAuthenticationService.IsLoggedIn)) { + if (dataContext.AuthService.IsLoggedIn) { + // dataContext.CurrentViewModel = new ClientViewModel(dataContext.AuthService); + dataContext.CurrentViewModel = App.Current.Host.Services.GetRequiredService<ClientViewModel>(); + } + else { + dataContext.CurrentViewModel = new LoginViewModel(dataContext.AuthService); + } + } + }; + + dataContext.Scale = cfg.Scale; + Width *= cfg.Scale; + Height *= cfg.Scale; + + appLifetime.ApplicationStopping.Register(() => { + Console.WriteLine("ApplicationStopping triggered"); + Close(); + }); + } + + protected override void OnKeyDown(KeyEventArgs e) => OnKeyDown(this, e); + + private void OnKeyDown(object? _, KeyEventArgs e) { + if (DataContext is not MainWindowViewModel viewModel) { + Console.WriteLine($"WARN: DataContext is {DataContext?.GetType().Name ?? "null"}, ignoring key press!"); + return; + } + + // Console.WriteLine("MainWindow KeyDown: " + e.Key); + if (e.Key == Key.Escape) { + viewModel.Scale = 1.0f; + } + else if (e.Key == Key.F1) { + viewModel.Scale -= 0.1f; + if (viewModel.Scale < 0.1f) { + viewModel.Scale = 0.1f; + } + } + else if (e.Key == Key.F2) { + viewModel.Scale += 0.1f; + if (viewModel.Scale > 5.0f) { + viewModel.Scale = 5.0f; + } + } + else if (e.Key == Key.K && e.KeyModifiers == KeyModifiers.Control) { + if (viewModel.CurrentViewModel is ClientViewModel clientViewModel) { + Console.WriteLine("QuickSwitcher invoked"); + } + else Console.WriteLine("WARN: CurrentViewModel is not ClientViewModel, ignoring Quick Switcher"); + } + } + + // ReSharper disable once AsyncVoidMethod + private async void PuppetButtonClicked(object? sender, RoutedEventArgs e) { + if (e.Source is not Button button) { + Console.WriteLine("WARN: Source is not Button, ignoring PuppetButtonClicked!"); + return; + } + + if (button.Tag is not User user) { + Console.WriteLine("WARN: Tag is not User, ignoring PuppetButtonClicked!"); + return; + } + + if (_auth.Homeserver is not AuthenticatedHomeserverSynapse synapse) { + Console.WriteLine("WARN: Homeserver is not Synapse, ignoring PuppetButtonClicked!"); + return; + } + + var puppet = await synapse.Admin.LoginUserAsync(user.Name, TimeSpan.FromMinutes(5)); + + System.Diagnostics.Process.Start(System.Diagnostics.Process.GetCurrentProcess().MainModule!.FileName, + (_cfg with { IsTemporary = true, LoginData = puppet.ToJson() }).Serialise()); + } +} \ No newline at end of file