-
-
Notifications
You must be signed in to change notification settings - Fork 445
Add Support for Automatically Checking Plugin Updates #3827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX. |
📝 Walkthrough## Walkthrough
These changes introduce automated plugin update functionality to the application. A background process periodically checks for plugin updates if enabled in user settings, supports bulk updating of plugins, and adds corresponding UI elements and localization strings. New settings and commands allow users to control and trigger plugin update checks from the interface.
## Changes
| File(s) | Change Summary |
|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| Flow.Launcher.Core/Plugin/PluginInstaller.cs | Added async method for checking and bulk updating plugins; supports silent and interactive modes. |
| Flow.Launcher.Infrastructure/UserSettings/Settings.cs | Added `AutoUpdatePlugins` boolean property to user settings. |
| Flow.Launcher/App.xaml.cs | Added static background method for periodic plugin update checks; refactored related startup logic.|
| Flow.Launcher/Languages/en.xaml | Added localization strings for plugin update features and tooltips. |
| Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs | Added async command for checking plugin updates from the plugin store view model. |
| Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | Added toggle for auto plugin updates and improved update-related card group formatting. |
| Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml | Added button to trigger plugin update checks in the plugin store UI. |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant User
participant App
participant Settings
participant PluginInstaller
participant UI
App->>Settings: Read AutoUpdatePlugins
alt AutoUpdatePlugins enabled
loop Every 5 hours
App->>PluginInstaller: CheckForPluginUpdatesAsync(silent=true)
PluginInstaller->>PluginInstaller: Update plugin manifest, compare versions
alt Updates available
PluginInstaller->>UI: Show update all plugins prompt
User->>UI: Click "Update all plugins"
UI->>PluginInstaller: UpdateAllPlugins()
PluginInstaller->>PluginInstaller: Download and update plugins
else No updates
PluginInstaller->>UI: Optionally show no updates message
end
end
end Possibly related PRs
Suggested reviewers
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
Flow.Launcher.Core/Plugin/PluginInstaller.cs (2)
294-313
: Consider refactoring the complex LINQ query for better readability.The LINQ query for finding updatable plugins is quite complex and could benefit from being broken down into smaller, more readable parts. Consider extracting the version comparison logic into a separate method.
Here's a suggested refactor:
- // Get all plugins that can be updated - var resultsForUpdate = ( - from existingPlugin in API.GetAllPlugins() - join pluginUpdateSource in API.GetPluginManifest() - on existingPlugin.Metadata.ID equals pluginUpdateSource.ID - where string.Compare(existingPlugin.Metadata.Version, pluginUpdateSource.Version, - StringComparison.InvariantCulture) < - 0 // if current version precedes version of the plugin from update source (e.g. PluginsManifest) - && !API.PluginModified(existingPlugin.Metadata.ID) - select - new - { - existingPlugin.Metadata.ID, - pluginUpdateSource.Name, - pluginUpdateSource.Author, - CurrentVersion = existingPlugin.Metadata.Version, - NewVersion = pluginUpdateSource.Version, - existingPlugin.Metadata.IcoPath, - PluginExistingMetadata = existingPlugin.Metadata, - PluginNewUserPlugin = pluginUpdateSource - }).ToList(); + // Get all plugins that can be updated + var resultsForUpdate = GetUpdatablePlugins().ToList(); + + // Add private method: + private static IEnumerable<dynamic> GetUpdatablePlugins() + { + return from existingPlugin in API.GetAllPlugins() + join pluginUpdateSource in API.GetPluginManifest() + on existingPlugin.Metadata.ID equals pluginUpdateSource.ID + where HasNewerVersion(existingPlugin.Metadata.Version, pluginUpdateSource.Version) + && !API.PluginModified(existingPlugin.Metadata.ID) + select CreateUpdateInfo(existingPlugin, pluginUpdateSource); + } + + private static bool HasNewerVersion(string currentVersion, string newVersion) + { + return string.Compare(currentVersion, newVersion, StringComparison.InvariantCulture) < 0; + }
284-284
: Fix typo in XML documentation.There's a typo in the parameter documentation.
- /// <param name="silentUpdate">If true, do not show any messages when there is no udpate available.</param> + /// <param name="silentUpdate">If true, do not show any messages when there is no update available.</param>Flow.Launcher/App.xaml.cs (1)
299-299
: Consider adding more descriptive comment.The comment could be more descriptive about what happens during plugin update checks.
- // check plugin updates every 5 hour + // check plugin updates every 5 hours (silent mode - only shows notifications if updates are available)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
Flow.Launcher.Core/Plugin/PluginInstaller.cs
(2 hunks)Flow.Launcher.Infrastructure/UserSettings/Settings.cs
(1 hunks)Flow.Launcher/App.xaml.cs
(4 hunks)Flow.Launcher/Languages/en.xaml
(4 hunks)Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs
(1 hunks)Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
(4 hunks)Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml
(1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml (2)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (2)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Flow.Launcher/App.xaml.cs (7)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3672
File: Flow.Launcher/MainWindow.xaml.cs:318-318
Timestamp: 2025-06-08T14:12:12.842Z
Learning: In Flow.Launcher, the App.NotifyIcon static property is initialized in the App class before MainWindow creation, so null checks are not needed when accessing App.NotifyIcon in MainWindow lifecycle methods.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3672
File: Flow.Launcher/MainWindow.xaml.cs:244-247
Timestamp: 2025-06-08T14:12:21.348Z
Learning: In Flow.Launcher, App.NotifyIcon is created before MainWindow creation, so null checks for App.NotifyIcon are not necessary when accessing it from MainWindow code.
Learnt from: Yusyuriv
PR: Flow-Launcher/Flow.Launcher#3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.
Learnt from: jjw24
PR: Flow-Launcher/Flow.Launcher#2448
File: Plugins/Flow.Launcher.Plugin.Sys/ThemeSelector.cs:16-20
Timestamp: 2025-01-18T10:10:18.414Z
Learning: In Flow Launcher's plugin system, the PluginInitContext parameter passed to plugin constructors is guaranteed to be non-null by the plugin initialization system, making null checks unnecessary.
Flow.Launcher.Infrastructure/UserSettings/Settings.cs (4)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: Yusyuriv
PR: Flow-Launcher/Flow.Launcher#3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Flow.Launcher.Core/Plugin/PluginInstaller.cs (3)
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Flow.Launcher/Languages/en.xaml (5)
Learnt from: taooceros
PR: Flow-Launcher/Flow.Launcher#2616
File: Flow.Launcher/Flow.Launcher.csproj:7-7
Timestamp: 2024-10-08T15:52:58.573Z
Learning: In the Flow Launcher project, the version number in the `Flow.Launcher.csproj` file is dynamically updated during the CI/CD process.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.
Learnt from: onesounds
PR: Flow-Launcher/Flow.Launcher#3394
File: Flow.Launcher/Themes/Darker Glass.xaml:134-141
Timestamp: 2025-03-28T21:12:13.386Z
Learning: In Flow.Launcher, hotkey styling is implemented with a two-component structure: a Border element with style `ItemHotkeyBGStyle` that provides background and border styling, containing a TextBlock with style `ItemHotkeyStyle` that handles the text styling.
Learnt from: onesounds
PR: Flow-Launcher/Flow.Launcher#0
File: :0-0
Timestamp: 2025-04-23T15:14:49.986Z
Learning: In WPF applications like Flow.Launcher, font styling should be applied using implicit styles instead of setting the FontFamily property on individual controls. Define implicit styles in a ResourceDictionary using <Style TargetType="{x:Type Button}"> format and merge it into App.xaml, which automatically applies the font to all instances of the control type while still allowing explicit overrides where needed.
Learnt from: Jack251970
PR: Flow-Launcher/Flow.Launcher#3672
File: Flow.Launcher/MainWindow.xaml.cs:318-318
Timestamp: 2025-06-08T14:12:12.842Z
Learning: In Flow.Launcher, the App.NotifyIcon static property is initialized in the App class before MainWindow creation, so null checks are not needed when accessing App.NotifyIcon in MainWindow lifecycle methods.
🧬 Code Graph Analysis (1)
Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (3)
Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs (1)
RelayCommand
(62-79)Flow.Launcher/ViewModel/MainViewModel.cs (2)
RelayCommand
(327-335)RelayCommand
(337-349)Flow.Launcher.Core/Plugin/PluginInstaller.cs (5)
Task
(34-113)Task
(120-159)Task
(166-214)Task
(222-279)PluginInstaller
(19-448)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: gitStream.cm
- GitHub Check: gitStream.cm
- GitHub Check: build
🔇 Additional comments (14)
Flow.Launcher.Core/Plugin/PluginInstaller.cs (1)
344-372
: Good concurrent update implementation with proper error handling.The implementation correctly uses
Task.WhenAll
for concurrent plugin updates and includes appropriate error handling for individual plugin update failures. The cancellation token usage and cleanup logic follow good practices.Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml (1)
102-108
: Clean UI implementation following existing patterns.The new plugin update button is properly integrated into the existing UI with consistent styling, appropriate positioning, and correct command binding. The use of a tooltip and icon follows the established design patterns.
Flow.Launcher.Infrastructure/UserSettings/Settings.cs (1)
236-236
: Well-positioned setting with appropriate default value.The new
AutoUpdatePlugins
property is logically placed near other update-related settings and defaults totrue
, which aligns with the PR objective of making the feature non-intrusive by default.Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs (1)
112-116
: Clean command implementation following established patterns.The new
CheckPluginUpdatesAsync
command properly uses the[RelayCommand]
attribute and calls the appropriatePluginInstaller
method withsilentUpdate: false
, which is correct for user-initiated update checks.Flow.Launcher/App.xaml.cs (2)
255-255
: Good refactoring to static methods for consistency.Converting
AutoStartup
andAutoUpdates
to static methods improves consistency since they only use static fields and don't require instance state.Also applies to: 276-276
293-308
: Well-implemented automatic plugin update functionality.The
AutoPluginUpdates
method correctly follows the same pattern asAutoUpdates
, usingPeriodicTimer
for consistent 5-hour intervals. The implementation properly respects the user setting and runs the update check both on startup and periodically.Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml (5)
185-186
: LGTM: Tooltip binding properly added.The tooltip binding for the auto-updates card follows the existing pattern and provides helpful user guidance.
245-245
: Correct card type adjustment for new grouping.Properly changed from "Last" to "Middle" to accommodate the new "autoUpdatePlugins" card being added to the group.
252-261
: Well-structured auto-update plugins card implementation.The new card follows the established pattern with proper:
- Localization key bindings for title and tooltip
- Consistent icon usage (matching the auto-updates card)
- Proper binding to
Settings.AutoUpdatePlugins
- Correct "Last" card type for the group
402-404
: Appropriate visibility binding for conditional UI.The visibility binding correctly shows the "ShouldUseDoublePinyin" card only when pinyin is enabled, improving the user experience by hiding irrelevant options.
415-416
: Logical visibility binding for double pinyin schema.Properly shows the schema selection only when double pinyin is enabled, maintaining a clean and contextual UI.
Flow.Launcher/Languages/en.xaml (3)
96-96
: Clear and informative tooltip text.The tooltip effectively explains the auto-update functionality to users, setting proper expectations about automatic checking and notification behavior.
154-155
: Consistent plugin auto-update strings.The title and tooltip follow the same pattern as the main auto-update feature, maintaining consistency in terminology and user messaging.
237-241
: Comprehensive plugin update UI strings.The new strings provide complete localization support for the plugin update checking feature:
- Clear status messages for both "no updates" and "updates available" scenarios
- Actionable button text for updating all plugins
- Helpful tooltip for the check updates functionality
All strings follow the established tone and style of the application.
Flow.Launcher/Languages/en.xaml
Outdated
<system:String x:Key="typingStartEn">Always Start Typing in English Mode</system:String> | ||
<system:String x:Key="typingStartEnTooltip">Temporarily change your input method to English mode when activating Flow.</system:String> | ||
<system:String x:Key="autoUpdates">Auto Update</system:String> | ||
<system:String x:Key="autoUpdatesTooltip">Automatically check app updates and notify if there are any updates available</system:String> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This auto update for the app actually updates so the description needs a bit more specific.
🥷 Code experts: onesounds Jack251970, onesounds have most 👩💻 activity in the files. See details
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame: ✨ Comment |
Co-authored-by: Jeremy Wu <[email protected]>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@check-spelling-bot Report🔴 Please reviewSee the 📂 files view, the 📜action log, or 📝 job summary for details.
See ❌ Event descriptions for more information. If the flagged items are 🤯 false positivesIf items relate to a ...
|
Changes
Test
One more thing
Since the plugin update message is implemented with message instead of message box which I do not think it will annoy users, I use default True value for Auto Update Plugins.