diff --git a/ScreenSound/Assets/kofi-button.png b/ScreenSound/Assets/kofi-button.png new file mode 100644 index 0000000..8926e9e Binary files /dev/null and b/ScreenSound/Assets/kofi-button.png differ diff --git a/ScreenSound/ScreenSound.csproj b/ScreenSound/ScreenSound.csproj index 90f1364..bd3bee2 100644 --- a/ScreenSound/ScreenSound.csproj +++ b/ScreenSound/ScreenSound.csproj @@ -52,6 +52,14 @@ --> + + diff --git a/ScreenSound/Views/MainWindow.xaml b/ScreenSound/Views/MainWindow.xaml index 4e8cbfe..717434c 100644 --- a/ScreenSound/Views/MainWindow.xaml +++ b/ScreenSound/Views/MainWindow.xaml @@ -89,6 +89,12 @@ + @@ -100,6 +106,17 @@ + + + + + + + @@ -598,6 +615,80 @@ + + + + + + + + + + + + + + + + ScreenSound is a solo developer project built in spare time. If it's + made your multi-monitor setup a little nicer, a one-off tip helps + justify the hours spent on bug fixes and new features — the app + stays free either way. + + + + + + + + + + diff --git a/ScreenSound/Views/MainWindow.xaml.cs b/ScreenSound/Views/MainWindow.xaml.cs index b6e81a3..b277d84 100644 --- a/ScreenSound/Views/MainWindow.xaml.cs +++ b/ScreenSound/Views/MainWindow.xaml.cs @@ -31,8 +31,8 @@ public MainWindow() DataContext = _viewModel; // Order must match the Tag indices on the sidebar RadioButtons: - // 0 = Home, 1 = Pinned, 2 = Settings, 3 = About. - _pages = new[] { HomePage, PinnedPage, SettingsPage, AboutPage }; + // 0 = Home, 1 = Pinned, 2 = Settings, 3 = About, 4 = Donate. + _pages = new[] { HomePage, PinnedPage, SettingsPage, AboutPage, DonatePage }; SetupTrayIcon(); @@ -363,6 +363,40 @@ private void RemovePinFromList_Click(object sender, RoutedEventArgs e) } } + // ── Donate page ─────────────────────────────────────────────────────── + + /// + /// Opens the Ko-fi donation page in the user's default browser. The + /// Donate tab's button is a bare image-button (no wpfui:Hyperlink) + /// so the ko-fi-yellow branded PNG renders pixel-perfect without any + /// Hyperlink chrome repainting over it — the trade-off is that URL + /// launching has to be wired here rather than inherited from NavigateUri. + /// + /// UseShellExecute=true is required for opening https:// URLs in + /// .NET 8 — without it + /// treats the URL as an executable path and throws Win32Exception. Any + /// failure (no default browser, shell error) is swallowed: the button + /// click is a best-effort nice-to-have, not something to crash the UI + /// over. + /// + private void KofiDonate_Click(object sender, RoutedEventArgs e) + { + try + { + System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo + { + FileName = "https://ko-fi.com/twibster", + UseShellExecute = true, + }); + } + catch + { + // Intentionally swallowed — a failed browser launch shouldn't + // crash the app or even surface an error dialog. The ToolTip + // already shows the URL so the user can copy/paste if needed. + } + } + protected override void OnClosing(CancelEventArgs e) { if (!_forceClose && _viewModel.MinimizeOnClose)