This commit is contained in:
rogier committed 2026-11-09 00:07:44 +01:00
1 parent e7ed05922e
commit cc08b00e3b
20 files changed
+1318 -32

No files matched your search

+212 -1
View File
@@ -10,6 +10,7 @@ using System.Windows.Media.Imaging;
using Kniip.Capture;
using Kniip.Editor;
using Kniip.Infrastructure;
using Kniip.Update;
using Kniip.Upload;
namespace Kniip.Settings;
@@ -35,6 +36,9 @@ public partial class SettingsWindow : Window
private string? _videoFolder;
private UploaderConfig? _uploader;
private bool _resetEditor;
private bool _updateChecked;
private ReleaseInfo? _update;
private System.Threading.CancellationTokenSource? _updateCts;
public SettingsWindow(AppSettings settings)
{
@@ -64,8 +68,13 @@ public partial class SettingsWindow : Window
? HotkeyHintText
: "De toetsenbordhaak kon niet worden gestart; de sneltoetsen werken nu niet.";
Deactivated += (_, _) => StopListening();
Closed += (_, _) => StopListening();
Closed += (_, _) =>
{
StopListening();
_updateCts?.Cancel();
};
CurrentVersionText.Text = $"Geïnstalleerde versie: {UpdateChecker.CurrentVersion}";
LoadFrom(settings);
MaxHeight = SystemParameters.WorkArea.Height;
@@ -86,6 +95,9 @@ public partial class SettingsWindow : Window
_snipFolder = settings.SnipSaveFolder;
_videoFolder = settings.VideoSaveFolder;
ShowSaveFolders();
SnipTemplateBox.Text = settings.SnipFileNameTemplate ?? string.Empty;
VideoTemplateBox.Text = settings.VideoFileNameTemplate ?? string.Empty;
ShowTemplatePreviews();
SaveAndCopyRadio.IsChecked = settings.SaveButton == SaveButtonChoice.SaveAndCopy;
SaveOnlyRadio.IsChecked = settings.SaveButton != SaveButtonChoice.SaveAndCopy;
@@ -233,6 +245,19 @@ public partial class SettingsWindow : Window
text.Foreground = string.IsNullOrEmpty(folder) ? (Brush)Application.Current.Resources["SubtleTextBrush"] : SystemColors.ControlTextBrush;
}
private void Template_TextChanged(object sender, TextChangedEventArgs e) => ShowTemplatePreviews();
private void ShowTemplatePreviews()
{
TemplateHelp.Text = FileNameTemplate.Help;
SnipTemplatePreview.Text = "Voorbeeld: " + FileNameTemplate.Preview(NullIfBlank(SnipTemplateBox.Text), "Cursor",
$"Knipsel {DateTime.Now:yyyy-MM-dd HHmmss}", ".png");
VideoTemplatePreview.Text = "Voorbeeld: " + FileNameTemplate.Preview(NullIfBlank(VideoTemplateBox.Text), "Cursor",
$"Screencast {DateTime.Now:yyyy-MM-dd HHmmss}", ".mp4");
}
private static string? NullIfBlank(string text) => string.IsNullOrWhiteSpace(text) ? null : text.Trim();
private void BrowseSaveFolder_Click(object sender, RoutedEventArgs e)
{
bool snip = sender is FrameworkElement { Tag: "Snip" };
@@ -396,6 +421,8 @@ public partial class SettingsWindow : Window
_settings.Uploader = _uploader;
_settings.SnipSaveFolder = _snipFolder;
_settings.VideoSaveFolder = _videoFolder;
_settings.SnipFileNameTemplate = NullIfBlank(SnipTemplateBox.Text);
_settings.VideoFileNameTemplate = NullIfBlank(VideoTemplateBox.Text);
_settings.SaveButton = SaveAndCopyRadio.IsChecked == true
? SaveButtonChoice.SaveAndCopy
: SaveButtonChoice.SaveOnly;
@@ -464,6 +491,190 @@ public partial class SettingsWindow : Window
if (e.OriginalSource is TabControl)
{
StopListening();
if (UpdateTab.IsSelected && !_updateChecked)
{
_ = CheckForUpdatesAsync();
}
}
}
private void CheckUpdate_Click(object sender, RoutedEventArgs e) => _ = CheckForUpdatesAsync();
private void ReleasePage_Click(object sender, RoutedEventArgs e) => OpenUrl(UpdateChecker.ReleasesPage);
private async System.Threading.Tasks.Task CheckForUpdatesAsync()
{
_updateChecked = true;
_updateCts?.Cancel();
var cts = new System.Threading.CancellationTokenSource();
_updateCts = cts;
_update = null;
UpdateButton.Visibility = Visibility.Collapsed;
CheckUpdateButton.IsEnabled = false;
UpdateStatus.Text = "Controleren op updates...";
try
{
IReadOnlyList<ReleaseInfo> releases = await UpdateChecker.GetReleasesAsync(cts.Token);
ShowReleases(releases);
}
catch (UpdateException ex)
{
UpdateStatus.Text = ex.Message;
ShowChangelog(Array.Empty<ReleaseInfo>(), "Geen changelog beschikbaar.");
}
catch (OperationCanceledException)
{
return;
}
finally
{
if (_updateCts == cts)
{
_updateCts = null;
CheckUpdateButton.IsEnabled = true;
}
cts.Dispose();
}
}
private void ShowReleases(IReadOnlyList<ReleaseInfo> releases)
{
Version current = UpdateChecker.CurrentVersion;
List<ReleaseInfo> newer = releases.Where(r => r.Version > current).ToList();
if (newer.Count == 0)
{
UpdateStatus.Text = releases.Count == 0
? "Er zijn nog geen releases gepubliceerd."
: $"Je gebruikt de nieuwste versie ({current}).";
ReleaseInfo? notes = releases.FirstOrDefault(r => r.Version == current) ?? releases.FirstOrDefault();
ShowChangelog(notes == null ? Array.Empty<ReleaseInfo>() : new[] { notes }, "Geen changelog beschikbaar.");
return;
}
_update = newer.FirstOrDefault(r => r.InstallerUrl != null);
if (_update != null)
{
UpdateStatus.Text = $"Versie {_update.Version} is beschikbaar.";
UpdateButton.Content = $"Updaten naar {_update.Version}";
UpdateButton.Visibility = Visibility.Visible;
}
else
{
UpdateStatus.Text = $"Versie {newer[0].Version} is beschikbaar, maar zonder installer. Download die via de releasepagina.";
}
ShowChangelog(newer, null);
}
private void ShowChangelog(IReadOnlyList<ReleaseInfo> releases, string? emptyText)
{
FlowDocument document = MarkdownRenderer.CreateDocument();
var culture = System.Globalization.CultureInfo.GetCultureInfo("nl-NL");
var baseUri = new Uri(UpdateChecker.RepositoryUrl);
foreach (ReleaseInfo release in releases)
{
Paragraph heading = MarkdownRenderer.Heading($"Versie {release.Version}", 17,
new Thickness(0, document.Blocks.Count == 0 ? 0 : 14, 0, 0));
document.Blocks.Add(heading);
if (release.Date is DateTimeOffset date)
{
document.Blocks.Add(new Paragraph(new Run(date.ToLocalTime().ToString("d MMMM yyyy", culture)))
{
Foreground = (Brush)Application.Current.Resources["SubtleTextBrush"],
FontSize = 12,
Margin = new Thickness(0, 0, 0, 8),
});
}
if (string.IsNullOrWhiteSpace(release.Body))
{
document.Blocks.Add(new Paragraph(new Run("Geen beschrijving."))
{
Foreground = (Brush)Application.Current.Resources["SubtleTextBrush"],
});
}
else
{
MarkdownRenderer.Append(document, release.Body, baseUri);
}
}
if (releases.Count == 0 && emptyText != null)
{
document.Blocks.Add(new Paragraph(new Run(emptyText))
{
Foreground = (Brush)Application.Current.Resources["SubtleTextBrush"],
});
}
ChangelogViewer.Document = document;
}
private async void Update_Click(object sender, RoutedEventArgs e)
{
if (_update is not { } release)
{
return;
}
string installFolder = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Programs", "Kniip");
bool installed = Environment.ProcessPath is { } exe
&& string.Equals(System.IO.Path.GetDirectoryName(exe), installFolder, StringComparison.OrdinalIgnoreCase);
string message = $"kniip wordt afgesloten, bijgewerkt naar versie {release.Version} en daarna opnieuw gestart. " +
"Open editors en screencasts worden eerst gesloten.";
if (!installed)
{
message += $"\n\nDeze kniip is niet via de installer gestart; de nieuwe versie wordt geïnstalleerd in {installFolder}.";
}
if (MessageBox.Show(this, message, "kniip bijwerken", MessageBoxButton.OKCancel, MessageBoxImage.Information) != MessageBoxResult.OK)
{
return;
}
var cts = new System.Threading.CancellationTokenSource();
_updateCts = cts;
UpdateButton.IsEnabled = false;
CheckUpdateButton.IsEnabled = false;
DownloadProgress.Value = 0;
DownloadProgress.Visibility = Visibility.Visible;
UpdateStatus.Text = $"Versie {release.Version} downloaden...";
string path;
try
{
path = await UpdateInstaller.DownloadAsync(release, new Progress<double>(p => DownloadProgress.Value = p), cts.Token);
}
catch (OperationCanceledException)
{
return;
}
catch (Exception ex) when (ex is UpdateException or System.IO.IOException or UnauthorizedAccessException)
{
UpdateStatus.Text = $"Versie {release.Version} is beschikbaar.";
MessageBox.Show(this, $"De update kon niet worden gedownload.\n\n{ex.Message}", "kniip",
MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
finally
{
if (_updateCts == cts)
{
_updateCts = null;
}
cts.Dispose();
if (IsLoaded)
{
DownloadProgress.Visibility = Visibility.Collapsed;
UpdateButton.IsEnabled = true;
CheckUpdateButton.IsEnabled = true;
}
}
UpdateStatus.Text = "Installer starten...";
App.Instance.InstallUpdate(path);
}
}