Added pasting and sending features
This commit is contained in:
@@ -2,6 +2,7 @@ using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using EbbesMemeClipboard.Models;
|
||||
using EbbesMemeClipboard.Services;
|
||||
|
||||
namespace EbbesMemeClipboard.ViewModels;
|
||||
@@ -10,6 +11,8 @@ public partial class PickerViewModel : ObservableObject
|
||||
{
|
||||
private readonly ILocalMemeLibraryService _library;
|
||||
private readonly IClipboardService _clipboard;
|
||||
private readonly ISettingsService _settings;
|
||||
private readonly IAutoPasteService _autoPaste;
|
||||
|
||||
public ObservableCollection<MemeTileViewModel> Items { get; } = new();
|
||||
|
||||
@@ -19,12 +22,26 @@ public partial class PickerViewModel : ObservableObject
|
||||
[ObservableProperty]
|
||||
private string _statusMessage = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// True while a modal dialog (currently: the "add memes" file picker) opened from within the
|
||||
/// picker is showing. The window's Deactivated handler checks this so opening that dialog
|
||||
/// doesn't get treated as "user clicked away" and hide the picker out from under it.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _isDialogOpen;
|
||||
|
||||
public event EventHandler? RequestClose;
|
||||
|
||||
public PickerViewModel(ILocalMemeLibraryService library, IClipboardService clipboard)
|
||||
public PickerViewModel(
|
||||
ILocalMemeLibraryService library,
|
||||
IClipboardService clipboard,
|
||||
ISettingsService settings,
|
||||
IAutoPasteService autoPaste)
|
||||
{
|
||||
_library = library;
|
||||
_clipboard = clipboard;
|
||||
_settings = settings;
|
||||
_autoPaste = autoPaste;
|
||||
RefreshItems();
|
||||
}
|
||||
|
||||
@@ -40,13 +57,32 @@ public partial class PickerViewModel : ObservableObject
|
||||
await _clipboard.CopyLocalFileAsync(tile.FullPath);
|
||||
StatusMessage = $"Copied {tile.DisplayName}";
|
||||
RequestClose?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
var mode = _settings.Current.InsertMode;
|
||||
if (mode is InsertMode.PasteIntoActiveWindow or InsertMode.PasteAndSend)
|
||||
{
|
||||
await _autoPaste.PasteAsync(alsoSend: mode == InsertMode.PasteAndSend);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"Couldn't copy {tile.DisplayName}: {ex.Message}";
|
||||
// Deliberately broad: CommunityToolkit's AsyncRelayCommand otherwise swallows any
|
||||
// exception here silently (no crash, no message, the click just appears to do
|
||||
// nothing), which makes clipboard/paste failures impossible to diagnose from the UI.
|
||||
StatusMessage = $"Couldn't insert {tile.DisplayName}: {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task RemoveItemAsync(MemeTileViewModel? tile)
|
||||
{
|
||||
if (tile is null) return;
|
||||
|
||||
await _library.RemoveAsync(tile.Record);
|
||||
RefreshItems();
|
||||
StatusMessage = $"Removed {tile.DisplayName}";
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ImportFilesAsync()
|
||||
{
|
||||
@@ -57,9 +93,17 @@ public partial class PickerViewModel : ObservableObject
|
||||
Title = "Add memes",
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() == true)
|
||||
IsDialogOpen = true;
|
||||
try
|
||||
{
|
||||
await ImportPathsAsync(dialog.FileNames);
|
||||
if (dialog.ShowDialog() == true)
|
||||
{
|
||||
await ImportPathsAsync(dialog.FileNames);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsDialogOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Windows.Input;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using EbbesMemeClipboard.Models;
|
||||
using EbbesMemeClipboard.Services;
|
||||
|
||||
namespace EbbesMemeClipboard.ViewModels;
|
||||
|
||||
public partial class SettingsViewModel : ObservableObject
|
||||
{
|
||||
private readonly ISettingsService _settings;
|
||||
private readonly IGlobalHotkeyService _hotkeyService;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _hotkeyDisplay = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _hotkeyError = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private InsertMode _insertMode;
|
||||
|
||||
public bool IsCopyOnly
|
||||
{
|
||||
get => InsertMode == InsertMode.CopyOnly;
|
||||
set { if (value) InsertMode = InsertMode.CopyOnly; }
|
||||
}
|
||||
|
||||
public bool IsPasteIntoActiveWindow
|
||||
{
|
||||
get => InsertMode == InsertMode.PasteIntoActiveWindow;
|
||||
set { if (value) InsertMode = InsertMode.PasteIntoActiveWindow; }
|
||||
}
|
||||
|
||||
public bool IsPasteAndSend
|
||||
{
|
||||
get => InsertMode == InsertMode.PasteAndSend;
|
||||
set { if (value) InsertMode = InsertMode.PasteAndSend; }
|
||||
}
|
||||
|
||||
public SettingsViewModel(ISettingsService settings, IGlobalHotkeyService hotkeyService)
|
||||
{
|
||||
_settings = settings;
|
||||
_hotkeyService = hotkeyService;
|
||||
_insertMode = _settings.Current.InsertMode;
|
||||
_hotkeyDisplay = HotkeyFormatter.Format(_settings.Current.HotkeyModifiers, _settings.Current.HotkeyKey);
|
||||
}
|
||||
|
||||
partial void OnInsertModeChanged(InsertMode value)
|
||||
{
|
||||
_settings.Current.InsertMode = value;
|
||||
_ = _settings.SaveAsync();
|
||||
OnPropertyChanged(nameof(IsCopyOnly));
|
||||
OnPropertyChanged(nameof(IsPasteIntoActiveWindow));
|
||||
OnPropertyChanged(nameof(IsPasteAndSend));
|
||||
}
|
||||
|
||||
public void TrySetHotkey(ModifierKeys modifiers, Key key)
|
||||
{
|
||||
if (_hotkeyService.Register(modifiers, key))
|
||||
{
|
||||
_settings.Current.HotkeyModifiers = modifiers;
|
||||
_settings.Current.HotkeyKey = key;
|
||||
_ = _settings.SaveAsync();
|
||||
HotkeyDisplay = HotkeyFormatter.Format(modifiers, key);
|
||||
HotkeyError = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Register() unregisters the old combo before trying the new one, so on failure
|
||||
// nothing is registered at all - restore the last-known-working combo rather than
|
||||
// leaving the app with no working hotkey.
|
||||
_hotkeyService.Register(_settings.Current.HotkeyModifiers, _settings.Current.HotkeyKey);
|
||||
HotkeyError = "That shortcut is already in use - try a different one.";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user