Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A lot of small improvements #13

Merged
merged 7 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/ChatPrisma/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,19 @@ private IHostBuilder CreateHostBuilder(string[] args) => Microsoft.Extensions.Ho
o.Key = "Y";
o.KeyModifiers = "Ctrl+Shift+Alt";
o.HotkeyDelayInMilliseconds = 500;
o.ClipboardDelayInMilliseconds = 500;
})
.BindConfiguration("Hotkey")
.ValidateDataAnnotations()
.ValidateOnStart();
services.AddOptions<TextEnhancementOptions>()
.Configure(o =>
{
o.TextSize = 12;
})
.BindConfiguration("TextEnhancement")
.ValidateDataAnnotations()
.ValidateOnStart();

// Services
services.AddSingleton<IKeyboardHooks, GlobalKeyInterceptorKeyboardHooks>();
Expand Down
18 changes: 2 additions & 16 deletions src/ChatPrisma/HostedServices/PrismaHostedService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,13 @@ public Task StopAsync(CancellationToken cancellationToken)
return Task.CompletedTask;
}

private bool _alreadyShowing;

private async void KeyboardHooksOnCombinationPressed(object? sender, EventArgs e)
{
// Only allow one text to be enhanced at a time
if (this._alreadyShowing)
return;

var text = await textExtractor.GetCurrentTextAsync();
if (text is null)
return;

this._alreadyShowing = true;
try
{
var textEnhancementViewModel = viewModelFactory.CreateTextEnhancementViewModel(text);
await dialogService.ShowDialog(textEnhancementViewModel);
}
finally
{
this._alreadyShowing = false;
}
var textEnhancementViewModel = viewModelFactory.CreateTextEnhancementViewModel(text);
await dialogService.ShowDialog(textEnhancementViewModel);
}
}
1 change: 1 addition & 0 deletions src/ChatPrisma/Options/HotkeyOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public class HotkeyOptions
[Required]
public string KeyModifiers { get; set; } = default!;
public int HotkeyDelayInMilliseconds { get; set; }
public int ClipboardDelayInMilliseconds { get; set; }
}
}
6 changes: 6 additions & 0 deletions src/ChatPrisma/Options/TextEnhancementOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ChatPrisma.Options;

public class TextEnhancementOptions
{
public int TextSize { get; set; }
}
25 changes: 24 additions & 1 deletion src/ChatPrisma/Services/TextExtractor/ClipboardTextExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public class ClipboardTextExtractor(IOptionsMonitor<HotkeyOptions> hotkeyOptions
Clipboard.Clear();
SendKeys.SendWait("^c");

var selectedText = Clipboard.GetText();
// It can take a while until the text is in the clipboard
var selectedText = await this.WaitUntilClipboardTextIsAvailable();

if (string.IsNullOrWhiteSpace(selectedText))
return null;
Expand Down Expand Up @@ -72,4 +73,26 @@ private static bool AnyKeyPressed()

return false;
}

private async Task<string?> WaitUntilClipboardTextIsAvailable()
{
var task = Task.Delay(TimeSpan.FromMilliseconds(hotkeyOptions.CurrentValue.ClipboardDelayInMilliseconds));
var watch = Stopwatch.StartNew();

// Either wait until the task is completed or the user releases all keys
while (task.IsCompleted is false)
{
var dataObject = Clipboard.GetDataObject();
if (dataObject?.GetData(DataFormats.Text) is string text)
{
logger.LogInformation("Early exit from WaitUntilClipboardIsFilled because we got some text from the clipboard (after {Time} ms)", watch.Elapsed.TotalMilliseconds);
return text;
}

await Task.Delay(10);
}

logger.LogInformation("Sadly no text available in clipboard (after {Time} ms)", watch.Elapsed.TotalMilliseconds);
return null;
}
}
2 changes: 1 addition & 1 deletion src/ChatPrisma/Themes/ContextMenuStyles.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
</Grid>

<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="MenuItemBorder" Property="Background">
<Setter.Value>
<SolidColorBrush Color="Black" Opacity="0.5" />
Expand Down
24 changes: 23 additions & 1 deletion src/ChatPrisma/Themes/TextBoxStyles.xaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:themes="clr-namespace:ChatPrisma.Themes">
xmlns:themes="clr-namespace:ChatPrisma.Themes"
xmlns:wpf="clr-namespace:FluentIcons.WPF;assembly=FluentIcons.WPF">
<Style TargetType="TextBox">
<Setter Property="Foreground" Value="White"/>
<Setter Property="CaretBrush" Value="White"/>
<Setter Property="Height" Value="30"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Command="Cut">
<MenuItem.Icon>
<wpf:SymbolIcon Symbol="Cut" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Command="Copy">
<MenuItem.Icon>
<wpf:SymbolIcon Symbol="Copy" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Command="Paste">
<MenuItem.Icon>
<wpf:SymbolIcon Symbol="ClipboardPaste" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
Expand Down
13 changes: 10 additions & 3 deletions src/ChatPrisma/Views/TextEnhancement/TextEnhancementView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"

Width="400"
Width="600"

MinHeight="200"
MaxHeight="800"

d:DataContext="{d:DesignInstance local:TextEnhancementViewModel}"

Expand All @@ -24,8 +26,13 @@
</Grid.RowDefinitions>

<GroupBox Grid.Row="0" Header="Text" themes:Attached.Icon="TextEditStyle">
<emoji:TextBlock Text="{Binding CurrentText}"
TextWrapping="Wrap"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" x:Name="TextScrollViewer">
<emoji:TextBlock x:Name="TextTextBlock"
Text="{Binding CurrentText}"
FontSize="{Binding TextSize}"
TextWrapping="Wrap"
SizeChanged="TextTextBlock_OnSizeChanged"/>
</ScrollViewer>
</GroupBox>

<GroupBox Grid.Row="1" Header="Änderungen" themes:Attached.Icon="InkingTool">
Expand Down
29 changes: 28 additions & 1 deletion src/ChatPrisma/Views/TextEnhancement/TextEnhancementView.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Threading;

namespace ChatPrisma.Views.TextEnhancement;

Expand All @@ -7,6 +10,24 @@ public partial class TextEnhancementView
private void TextEnhancementView_OnLoaded(object sender, RoutedEventArgs e)
{
this.InstructionTextBox.Focus();

// Place window slightly to the top
var window = Window.GetWindow(this)!;
window.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
{
var helper = new WindowInteropHelper(window);
var currentScreen = Screen.FromHandle(helper.Handle);
var currentScreenHeight = currentScreen.Bounds.Height;

// Place the window a bit moved to the top, so it is perfectly centered if we reach this.MaxHeight
window.Top = Math.Max((currentScreenHeight - this.MaxHeight) / 2, 0);
}));

// Ensure window is shown above all other windows
window.Activate();
window.Topmost = true;
window.Topmost = false;
window.Focus();
}

private void TextEnhancementView_OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
Expand All @@ -27,4 +48,10 @@ private void ViewModelOnApplyInstructionCancelled(object? sender, EventArgs e)
// Set cursor at the end of the instruction textbox
this.InstructionTextBox.Select(this.InstructionTextBox.Text.Length, 0);
}
}

private void TextTextBlock_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
// Keep the ScrollViewer scrolled to the bottom while the text is generating
this.TextScrollViewer.ScrollToVerticalOffset(this.TextScrollViewer.ExtentHeight);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System.Windows;
using ChatPrisma.Options;
using ChatPrisma.Services.ChatBot;
using ChatPrisma.Services.Dialogs;
using ChatPrisma.Services.TextWriter;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.Options;

namespace ChatPrisma.Views.TextEnhancement;

public partial class TextEnhancementViewModel(string inputText, IClipboardTextWriter clipboardTextWriter, IChatBotService chatBotService) : ObservableObject, ICloseWindow, IConfigureWindow
public partial class TextEnhancementViewModel(string inputText, IClipboardTextWriter clipboardTextWriter, IChatBotService chatBotService, IOptionsMonitor<TextEnhancementOptions> textEnhancementOptions) : ObservableObject, ICloseWindow, IConfigureWindow
{
private List<PrismaChatMessage> _allMessages = new()
{
Expand All @@ -23,6 +25,9 @@ public partial class TextEnhancementViewModel(string inputText, IClipboardTextWr
[ObservableProperty]
private string _instruction = string.Empty;

[ObservableProperty]
private int _textSize = textEnhancementOptions.CurrentValue.TextSize;

public event EventHandler? ApplyInstructionCancelled;

[RelayCommand(IncludeCancelCommand = true)]
Expand Down
4 changes: 4 additions & 0 deletions src/ChatPrisma/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"Key": "Y",
"KeyModifiers": "Ctrl+Shift+Alt",
"HotkeyDelayInMilliseconds": 500,
"ClipboardDelayInMilliseconds": 500,
},
"TextEnhancement": {
"TextSize": 12,
},
"NLog": {
"throwConfigExceptions": true,
Expand Down