From f5d3acbe233bc9603a1b36f129148c400cf2fd3d Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 3 Jan 2023 23:23:56 -0500 Subject: [PATCH 01/81] Catch General Exception when checking update, and use PeriodicTimer to avoid error to crash the main thread --- Flow.Launcher.Core/Updater.cs | 10 +++++++--- Flow.Launcher/App.xaml.cs | 20 +++++++++----------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 91de8298c..3f64b273e 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -33,7 +33,7 @@ namespace Flow.Launcher.Core public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) { - await UpdateLock.WaitAsync(); + await UpdateLock.WaitAsync().ConfigureAwait(false); try { if (!silentUpdate) @@ -88,9 +88,13 @@ namespace Flow.Launcher.Core UpdateManager.RestartApp(Constant.ApplicationFileName); } } - catch (Exception e) when (e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException) + catch (Exception e) { - Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); + if ((e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)) + Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); + else + Log.Exception($"|Updater.UpdateApp|Error Occurred", e); + if (!silentUpdate) api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), api.GetTranslation("update_flowlauncher_check_connection")); diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 43fa0eddb..9df936e76 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Windows; @@ -84,7 +85,7 @@ namespace Flow.Launcher Current.MainWindow = window; Current.MainWindow.Title = Constant.FlowLauncher; - + HotKeyMapper.Initialize(_mainVM); // happlebao todo temp fix for instance code logic @@ -130,20 +131,17 @@ namespace Flow.Launcher //[Conditional("RELEASE")] private void AutoUpdates() { - Task.Run(async () => + _ = Task.Run(async () => { if (_settings.AutoUpdates) { - // check udpate every 5 hours - var timer = new Timer(1000 * 60 * 60 * 5); - timer.Elapsed += async (s, e) => - { - await _updater.UpdateAppAsync(API); - }; - timer.Start(); - - // check updates on startup + // check update every 5 hours + var timer = new PeriodicTimer(TimeSpan.FromHours(5)); await _updater.UpdateAppAsync(API); + + while (await timer.WaitForNextTickAsync()) + // check updates on startup + await _updater.UpdateAppAsync(API); } }); } From c2137011e8ae13781207b67ddbdc73e8c09bebc0 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Sat, 7 Jan 2023 22:15:57 +1100 Subject: [PATCH 02/81] Update comment --- Flow.Launcher/App.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 9df936e76..4ae754fcd 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -88,7 +88,7 @@ namespace Flow.Launcher HotKeyMapper.Initialize(_mainVM); - // happlebao todo temp fix for instance code logic + // todo temp fix for instance code logic // load plugin before change language, because plugin language also needs be changed InternationalizationManager.Instance.Settings = _settings; InternationalizationManager.Instance.ChangeLanguage(_settings.Language); From dfe2c01fb5745381561724e417899c1686e53196 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 7 Jan 2023 09:14:18 -0600 Subject: [PATCH 03/81] fix spelling --- Flow.Launcher/App.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 4ae754fcd..1d398276d 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -92,7 +92,7 @@ namespace Flow.Launcher // load plugin before change language, because plugin language also needs be changed InternationalizationManager.Instance.Settings = _settings; InternationalizationManager.Instance.ChangeLanguage(_settings.Language); - // main windows needs initialized before theme change because of blur settigns + // main windows needs initialized before theme change because of blur settings ThemeManager.Instance.Settings = _settings; ThemeManager.Instance.ChangeTheme(_settings.Theme); From 8b517954ef905a87b2ea54dd743c06fabffacca9 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 7 Jan 2023 13:11:43 -0600 Subject: [PATCH 04/81] Try Atomic Save for Setting --- Flow.Launcher.Infrastructure/Helper.cs | 6 +- .../Storage/JsonStorage.cs | 89 +++++++++++-------- .../Storage/PluginJsonStorage.cs | 2 +- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Helper.cs b/Flow.Launcher.Infrastructure/Helper.cs index faa4c93b5..db575de90 100644 --- a/Flow.Launcher.Infrastructure/Helper.cs +++ b/Flow.Launcher.Infrastructure/Helper.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.IO; using System.Runtime.CompilerServices; using System.Text.Json; @@ -16,7 +18,7 @@ namespace Flow.Launcher.Infrastructure /// /// http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy /// - public static T NonNull(this T obj) + public static T NonNull(this T? obj) { if (obj == null) { diff --git a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs index 0083ccb87..20b2e4e21 100644 --- a/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs @@ -1,4 +1,5 @@ -using System; +#nullable enable +using System; using System.Globalization; using System.IO; using System.Text.Json; @@ -11,62 +12,73 @@ namespace Flow.Launcher.Infrastructure.Storage /// public class JsonStorage where T : new() { - protected T _data; + protected T? Data; // need a new directory name public const string DirectoryName = "Settings"; public const string FileSuffix = ".json"; - public string FilePath { get; set; } - public string DirectoryPath { get; set; } + protected string FilePath { get; init; } = null!; + private string TempFilePath => $"{FilePath}.tmp"; + private string BackupFilePath => $"{FilePath}.bak"; + protected string DirectoryPath { get; init; } = null!; public T Load() { + string? serialized = null; + if (File.Exists(FilePath)) { - var serialized = File.ReadAllText(FilePath); - if (!string.IsNullOrWhiteSpace(serialized)) + serialized = File.ReadAllText(FilePath); + } + + if (!string.IsNullOrEmpty(serialized)) + { + try { - Deserialize(serialized); + Data = JsonSerializer.Deserialize(serialized)?? TryLoadBackup() ?? LoadDefault(); } - else + catch (JsonException) { - LoadDefault(); + Data = TryLoadBackup() ?? LoadDefault(); } } else { - LoadDefault(); + Data = TryLoadBackup() ?? LoadDefault(); } - return _data.NonNull(); + return Data.NonNull(); } - private void Deserialize(string serialized) - { - try - { - _data = JsonSerializer.Deserialize(serialized); - } - catch (JsonException e) - { - LoadDefault(); - Log.Exception($"|JsonStorage.Deserialize|Deserialize error for json <{FilePath}>", e); - } - - if (_data == null) - { - LoadDefault(); - } - } - - private void LoadDefault() + private T LoadDefault() { if (File.Exists(FilePath)) { BackupOriginFile(); } - _data = new T(); - Save(); + return new T(); + } + + private T? TryLoadBackup() + { + if (!File.Exists(BackupFilePath)) + return default; + + try + { + var data = JsonSerializer.Deserialize(File.ReadAllText(BackupFilePath)); + if (data != null) + { + Log.Info($"|JsonStorage.Load|Load backup file {BackupFilePath} successfully"); + File.Replace(BackupFilePath, FilePath, null); + return data; + } + return default; + } + catch (JsonException) + { + return default; + } } private void BackupOriginFile() @@ -82,13 +94,14 @@ namespace Flow.Launcher.Infrastructure.Storage public void Save() { - string serialized = JsonSerializer.Serialize(_data, new JsonSerializerOptions() { WriteIndented = true }); + string serialized = JsonSerializer.Serialize(Data, new JsonSerializerOptions + { + WriteIndented = true + }); - File.WriteAllText(FilePath, serialized); + File.WriteAllText(TempFilePath, serialized); + File.Replace(TempFilePath, FilePath, BackupFilePath); + File.Delete(TempFilePath); } } - - [Obsolete("Deprecated as of Flow Launcher v1.8.0, on 2021.06.21. " + - "This is used only for Everything plugin v1.4.9 or below backwards compatibility")] - public class JsonStrorage : JsonStorage where T : new() { } } diff --git a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs index 923a1a6b5..abe3f55b5 100644 --- a/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs +++ b/Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs @@ -18,7 +18,7 @@ namespace Flow.Launcher.Infrastructure.Storage public PluginJsonStorage(T data) : this() { - _data = data; + Data = data; } } } From 43e38f648c92cc93512cab8ade7ccd5de75dec2b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 7 Jan 2023 13:22:17 -0600 Subject: [PATCH 05/81] update expect.txt --- .github/actions/spelling/expect.txt | 110 ++++++++++++++-------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index a91287cc0..612ee3957 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -1,64 +1,64 @@ -crowdin -DWM -workflows -wpf actionkeyword -stackoverflow -Wox -flowlauncher -Fody -stackoverflow -IContext -IShell -IPlugin -appveyor -netflix -youtube -appdata -Prioritise -Segoe -Google -Customise -UWP -uwp -Bokmal -Bokm -uninstallation -uninstalling -voidtools -fullscreen -hotkeys -totalcmd -lnk amazonaws -mscorlib -pythonw +appdata +appref +appref-ms +appveyor +baidu +bak +Bokm +Bokmal +CMD +crowdin +Customise +dlgtext dotnet -winget -jjw24 -wolframalpha -gmail +dpi duckduckgo +DWM +EWX facebook findicon -baidu -pls -websearch -qianlifeng -userdata -srchadmin -EWX -dlgtext -CMD -appref-ms -appref -TSource -runas -dpi -popup -ptr -pluginindicator -TobiasSekan +flowlauncher +Fody +fullscreen +gmail +Google +hotkeys +IContext Img img +IPlugin +IShell +jjw24 +lnk +mscorlib +netflix +pls +pluginindicator +popup +Prioritise +ptr +pythonw +qianlifeng resx +runas +Segoe +srchadmin +stackoverflow +TobiasSekan +totalcmd +TSource +uninstallation +uninstalling +userdata +UWP +uwp +voidtools +websearch +winget +wolframalpha +workflows +Wox +wpf +youtube From 1e256e441816628e6ef479ac6f7d5d79dff8f4d1 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 7 Jan 2023 13:22:58 -0600 Subject: [PATCH 06/81] Revert "update expect.txt" This reverts commit 43e38f648c92cc93512cab8ade7ccd5de75dec2b. --- .github/actions/spelling/expect.txt | 108 ++++++++++++++-------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 612ee3957..a91287cc0 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -1,64 +1,64 @@ -actionkeyword -amazonaws -appdata -appref -appref-ms -appveyor -baidu -bak -Bokm -Bokmal -CMD crowdin -Customise -dlgtext -dotnet -dpi -duckduckgo DWM -EWX -facebook -findicon +workflows +wpf +actionkeyword +stackoverflow +Wox flowlauncher Fody -fullscreen -gmail -Google -hotkeys -IContext -Img -img -IPlugin -IShell -jjw24 -lnk -mscorlib -netflix -pls -pluginindicator -popup -Prioritise -ptr -pythonw -qianlifeng -resx -runas -Segoe -srchadmin stackoverflow -TobiasSekan -totalcmd -TSource -uninstallation -uninstalling -userdata +IContext +IShell +IPlugin +appveyor +netflix +youtube +appdata +Prioritise +Segoe +Google +Customise UWP uwp +Bokmal +Bokm +uninstallation +uninstalling voidtools -websearch +fullscreen +hotkeys +totalcmd +lnk +amazonaws +mscorlib +pythonw +dotnet winget +jjw24 wolframalpha -workflows -Wox -wpf -youtube +gmail +duckduckgo +facebook +findicon +baidu +pls +websearch +qianlifeng +userdata +srchadmin +EWX +dlgtext +CMD +appref-ms +appref +TSource +runas +dpi +popup +ptr +pluginindicator +TobiasSekan +Img +img +resx From 162add930700059ed901c79b3a66b292c77de491 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 7 Jan 2023 13:24:19 -0600 Subject: [PATCH 07/81] update expect.txt --- .github/actions/spelling/expect.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index a91287cc0..ba6faec9a 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -62,3 +62,5 @@ TobiasSekan Img img resx +bak +tmp From a92ebf5756ba6f937189f3c30becbd88e3104040 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 8 Jan 2023 16:31:37 -0600 Subject: [PATCH 08/81] Dynamic Height and Dynamic Icon Size --- .../DiameterToCenterPointConverter.cs | 25 +++ .../Converters/IconRadiusConverter.cs | 27 +++ Flow.Launcher/ResultListBox.xaml | 155 +++++++++++------- Flow.Launcher/Themes/Base.xaml | 8 + Flow.Launcher/ViewModel/ResultsViewModel.cs | 2 +- 5 files changed, 156 insertions(+), 61 deletions(-) create mode 100644 Flow.Launcher/Converters/DiameterToCenterPointConverter.cs create mode 100644 Flow.Launcher/Converters/IconRadiusConverter.cs diff --git a/Flow.Launcher/Converters/DiameterToCenterPointConverter.cs b/Flow.Launcher/Converters/DiameterToCenterPointConverter.cs new file mode 100644 index 000000000..e81bb2507 --- /dev/null +++ b/Flow.Launcher/Converters/DiameterToCenterPointConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; + +namespace Flow.Launcher.Converters +{ + public class DiameterToCenterPointConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is double d) + { + return new Point(d / 2, d / 2); + } + + return new Point(0, 0); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/Flow.Launcher/Converters/IconRadiusConverter.cs b/Flow.Launcher/Converters/IconRadiusConverter.cs new file mode 100644 index 000000000..51129cfb8 --- /dev/null +++ b/Flow.Launcher/Converters/IconRadiusConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using Windows.Devices.PointOfService; + +namespace Flow.Launcher.Converters +{ + public class IconRadiusConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length != 2) + throw new ArgumentException("IconRadiusConverter must have 2 parameters"); + + return values[1] switch + { + true => (double)values[0] / 2, + false => (double)values[0], + _ => throw new ArgumentException("The second argument should be boolean", nameof(values)) + }; + } + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + } +} diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index 8f3238303..b2ab4a287 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -1,5 +1,4 @@ - + + + +