From ba35f1269b8632ee1c5a5178f56cb0086eae5bb1 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:07:01 +0800 Subject: [PATCH 01/30] Add GetString api function --- Flow.Launcher.Infrastructure/Http/Http.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Flow.Launcher.Infrastructure/Http/Http.cs b/Flow.Launcher.Infrastructure/Http/Http.cs index a29f8accf..22eb065f5 100644 --- a/Flow.Launcher.Infrastructure/Http/Http.cs +++ b/Flow.Launcher.Infrastructure/Http/Http.cs @@ -220,5 +220,18 @@ namespace Flow.Launcher.Infrastructure.Http return new HttpResponseMessage(HttpStatusCode.InternalServerError); } } + + public static async Task GetStringAsync(string url, CancellationToken token = default) + { + try + { + Log.Debug(ClassName, $"Url <{url}>"); + return await client.GetStringAsync(url, token); + } + catch (System.Exception e) + { + return string.Empty; + } + } } } From 1f4578c04ce64325a1ad0fd8b20548fc039239cc Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:08:32 +0800 Subject: [PATCH 02/30] Add release notes window --- Flow.Launcher/Flow.Launcher.csproj | 1 + Flow.Launcher/ReleaseNotesWindow.xaml | 168 +++++++++++++++++++++++ Flow.Launcher/ReleaseNotesWindow.xaml.cs | 149 ++++++++++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 Flow.Launcher/ReleaseNotesWindow.xaml create mode 100644 Flow.Launcher/ReleaseNotesWindow.xaml.cs diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 8d43eff98..4580798b2 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -90,6 +90,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml new file mode 100644 index 000000000..132de63c8 --- /dev/null +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs new file mode 100644 index 000000000..18c67ac5b --- /dev/null +++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using Flow.Launcher.Infrastructure.Http; + +namespace Flow.Launcher +{ + public partial class ReleaseNotesWindow : Window + { + public ReleaseNotesWindow() + { + InitializeComponent(); + } + + #region Window Events + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] + private async void Window_Loaded(object sender, RoutedEventArgs e) + { + RefreshMaximizeRestoreButton(); + MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync(); + } + + private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e) + { + Close(); + } + + #endregion + + #region Window Custom TitleBar + + private void OnMinimizeButtonClick(object sender, RoutedEventArgs e) + { + WindowState = WindowState.Minimized; + } + + private void OnMaximizeRestoreButtonClick(object sender, RoutedEventArgs e) + { + WindowState = WindowState switch + { + WindowState.Maximized => WindowState.Normal, + _ => WindowState.Maximized + }; + } + + private void OnCloseButtonClick(object sender, RoutedEventArgs e) + { + Close(); + } + + private void RefreshMaximizeRestoreButton() + { + if (WindowState == WindowState.Maximized) + { + MaximizeButton.Visibility = Visibility.Hidden; + RestoreButton.Visibility = Visibility.Visible; + } + else + { + MaximizeButton.Visibility = Visibility.Visible; + RestoreButton.Visibility = Visibility.Hidden; + } + } + + private void Window_StateChanged(object sender, EventArgs e) + { + RefreshMaximizeRestoreButton(); + } + + #endregion + + #region Release Notes + + private static async Task GetReleaseNotesMarkdownAsync() + { + var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases"); + var releases = JsonSerializer.Deserialize>(releaseNotesJSON); + + // Get the latest releases + var latestReleases = releases.OrderByDescending(release => release.PublishedDate).Take(3); + + // Build the release notes in Markdown format + var releaseNotesHtmlBuilder = new StringBuilder(string.Empty); + foreach (var release in latestReleases) + { + releaseNotesHtmlBuilder.AppendLine("# " + release.Name); + + // Add unit for images: Replace with + var notes = ImageUnitRegex().Replace(release.ReleaseNotes, m => + { + var prefix = m.Groups[1].Value; + var widthValue = m.Groups[2].Value; + var quote = m.Groups[3].Value; + var suffix = m.Groups[4].Value; + // Only replace if width is number like 500 without units like 500px + if (IsNumber(widthValue)) + return $"{prefix}{widthValue}px{quote}{suffix}"; + return m.Value; + }); + + releaseNotesHtmlBuilder.AppendLine(notes); + releaseNotesHtmlBuilder.AppendLine(" "); + } + + return releaseNotesHtmlBuilder.ToString(); + } + + private static bool IsNumber(string input) + { + if (string.IsNullOrEmpty(input)) + return false; + + foreach (char c in input) + { + if (!char.IsDigit(c)) + return false; + } + return true; + } + + private sealed class GitHubReleaseInfo + { + [JsonPropertyName("published_at")] + public DateTimeOffset PublishedDate { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("tag_name")] + public string TagName { get; set; } + + [JsonPropertyName("body")] + public string ReleaseNotes { get; set; } + } + + [GeneratedRegex("(]*width\\s*=\\s*[\"']?)(\\d+)([\"']?)([^>]*>)", RegexOptions.IgnoreCase, "en-GB")] + private static partial Regex ImageUnitRegex(); + + #endregion + } +} From 7117ba05ee4ef544f4bc0c7c648fa3e5f8c25971 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:08:41 +0800 Subject: [PATCH 03/30] Test release notes window --- Flow.Launcher/MainWindow.xaml.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index a77d6471c..b266d3dc0 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -132,6 +132,9 @@ namespace Flow.Launcher welcomeWindow.Show(); } + var releaseNotesWindow = new ReleaseNotesWindow(); + releaseNotesWindow.Show(); + // Initialize place holder SetupPlaceholderText(); _viewModel.PlaceholderText = _settings.PlaceholderText; From c241d21a4a9259a3ce1eb50f21b0624c6780cba0 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:51:26 +0800 Subject: [PATCH 04/30] Fix height --- Flow.Launcher/ReleaseNotesWindow.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml index 132de63c8..e61986aea 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -157,7 +157,7 @@ Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="5" - MaxHeight="510" + Height="510" Margin="15 0 20 0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" From af0e1180a5cbc18cba3090f10595e58ab12e7ac6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Fri, 6 Jun 2025 23:52:34 +0800 Subject: [PATCH 05/30] Use loaded event & Add style --- Flow.Launcher/ReleaseNotesWindow.xaml | 3 ++- Flow.Launcher/ReleaseNotesWindow.xaml.cs | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml index e61986aea..7b2e5f7e7 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -161,7 +161,8 @@ Margin="15 0 20 0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - ClickAction="SafetyDisplayWithRelativePath" /> + ClickAction="SafetyDisplayWithRelativePath" + Loaded="MarkdownViewer_Loaded" /> diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml.cs b/Flow.Launcher/ReleaseNotesWindow.xaml.cs index 18c67ac5b..4f0c1a9ce 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml.cs +++ b/Flow.Launcher/ReleaseNotesWindow.xaml.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using Flow.Launcher.Infrastructure.Http; +using MdXaml; namespace Flow.Launcher { @@ -21,11 +22,9 @@ namespace Flow.Launcher #region Window Events - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] - private async void Window_Loaded(object sender, RoutedEventArgs e) + private void Window_Loaded(object sender, RoutedEventArgs e) { RefreshMaximizeRestoreButton(); - MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync(); } private void OnCloseExecuted(object sender, ExecutedRoutedEventArgs e) @@ -82,6 +81,11 @@ namespace Flow.Launcher private static async Task GetReleaseNotesMarkdownAsync() { var releaseNotesJSON = await Http.GetStringAsync("https://api.github.com/repos/Flow-Launcher/Flow.Launcher/releases"); + + if (string.IsNullOrEmpty(releaseNotesJSON)) + { + return string.Empty; + } var releases = JsonSerializer.Deserialize>(releaseNotesJSON); // Get the latest releases @@ -145,5 +149,12 @@ namespace Flow.Launcher private static partial Regex ImageUnitRegex(); #endregion + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] + private async void MarkdownViewer_Loaded(object sender, RoutedEventArgs e) + { + MarkdownViewer.MarkdownStyle = MarkdownStyle.GithubLike; + MarkdownViewer.Markdown = await GetReleaseNotesMarkdownAsync(); + } } } From 02496214ea2cabbd0037bc83f3e9e03125311222 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Sat, 7 Jun 2025 00:07:44 +0800 Subject: [PATCH 06/30] Add progress ring --- Flow.Launcher/ReleaseNotesWindow.xaml | 23 ++++++++++++++++ Flow.Launcher/ReleaseNotesWindow.xaml.cs | 34 +++++++++++++++++++++--- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/ReleaseNotesWindow.xaml b/Flow.Launcher/ReleaseNotesWindow.xaml index 7b2e5f7e7..f70fa6f5c 100644 --- a/Flow.Launcher/ReleaseNotesWindow.xaml +++ b/Flow.Launcher/ReleaseNotesWindow.xaml @@ -163,6 +163,29 @@ VerticalAlignment="Stretch" ClickAction="SafetyDisplayWithRelativePath" Loaded="MarkdownViewer_Loaded" /> + + + + +