diff --git a/.cm/gitstream.cm b/.cm/gitstream.cm index fcf01c0fe..c372f5a6c 100644 --- a/.cm/gitstream.cm +++ b/.cm/gitstream.cm @@ -72,4 +72,8 @@ changes: # Sum all the line removed in the PR deletions: {{ branch.diff.files_metadata | map(attr='deletions') | sum }} # Calculate the ratio of new code - ratio: {{ (changes.additions / (changes.additions + changes.deletions)) * 100 | round(2) }} \ No newline at end of file + ratio: {{ (changes.additions / (changes.additions + changes.deletions)) * 100 | round(2) }} + +has: + screenshot_link: {{ pr.description | includes(regex=r/!\[.*\]\(.*(jpg|svg|png|gif|psd).*\)/) }} + image_uploaded: {{ pr.description | includes(regex=r//) }} \ No newline at end of file diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 02b486a02..6ba41e410 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -98,6 +98,7 @@ Português Português (Brasil) Italiano Slovenský +quicklook Tiếng Việt Droplex Preinstalled diff --git a/.github/workflows/pr_assignee.yml b/.github/workflows/pr_assignee.yml new file mode 100644 index 000000000..af6daff02 --- /dev/null +++ b/.github/workflows/pr_assignee.yml @@ -0,0 +1,19 @@ +name: Assign PR to creator + +# Due to GitHub token limitation, only able to assign org members not authors from forks. +# https://github.com/thomaseizinger/assign-pr-creator-action/issues/3 + +on: + pull_request: + types: [opened] + branches-ignore: + - l10n_dev + +jobs: + automation: + runs-on: ubuntu-latest + steps: + - name: Assign PR to creator + uses: thomaseizinger/assign-pr-creator-action@v1.0.0 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr_milestone.yml b/.github/workflows/pr_milestone.yml new file mode 100644 index 000000000..b343a39cc --- /dev/null +++ b/.github/workflows/pr_milestone.yml @@ -0,0 +1,19 @@ +name: Set Milestone + +# Assigns the earliest created milestone that matches the below glob pattern. + +on: + pull_request: + types: [opened] + +jobs: + automation: + runs-on: ubuntu-latest + + steps: + - name: set-milestone + uses: andrefcdias/add-to-milestone@v1.3.0 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + milestone: "+([0-9]).+([0-9]).+([0-9])" + use-expression: true diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index 3c8d654fe..b78331690 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -1,4 +1,4 @@ -using Flow.Launcher.Core.ExternalPlugins; +using Flow.Launcher.Core.ExternalPlugins; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -91,6 +91,48 @@ namespace Flow.Launcher.Core.Plugin }).ToArray()); } + public static async Task OpenExternalPreviewAsync(string path, bool sendFailToast = true) + { + await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch + { + IAsyncExternalPreview p => p.OpenPreviewAsync(path, sendFailToast), + _ => Task.CompletedTask, + }).ToArray()); + } + + public static async Task CloseExternalPreviewAsync() + { + await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch + { + IAsyncExternalPreview p => p.ClosePreviewAsync(), + _ => Task.CompletedTask, + }).ToArray()); + } + + public static async Task SwitchExternalPreviewAsync(string path, bool sendFailToast = true) + { + await Task.WhenAll(AllPlugins.Select(plugin => plugin.Plugin switch + { + IAsyncExternalPreview p => p.SwitchPreviewAsync(path, sendFailToast), + _ => Task.CompletedTask, + }).ToArray()); + } + + public static bool UseExternalPreview() + { + return GetPluginsForInterface().Any(x => !x.Metadata.Disabled); + } + + public static bool AllowAlwaysPreview() + { + var plugin = GetPluginsForInterface().FirstOrDefault(x => !x.Metadata.Disabled); + + if (plugin is null) + return false; + + return ((IAsyncExternalPreview)plugin.Plugin).AllowAlwaysPreview(); + } + static PluginManager() { // validate user directory diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 44e104895..0c7de10fd 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -185,7 +185,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings /// when false Alphabet static service will always return empty results /// public bool ShouldUsePinyin { get; set; } = false; + public bool AlwaysPreview { get; set; } = false; + public bool AlwaysStartEn { get; set; } = false; private SearchPrecisionScore _querySearchPrecision = SearchPrecisionScore.Regular; diff --git a/Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs b/Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs new file mode 100644 index 000000000..cc4f94c56 --- /dev/null +++ b/Flow.Launcher.Plugin/Interfaces/IAsyncExternalPreview.cs @@ -0,0 +1,40 @@ +using System.Threading.Tasks; + +namespace Flow.Launcher.Plugin +{ + /// + /// This interface is for plugins that wish to provide file preview (external preview) + /// via a third party app instead of the default preview. + /// + public interface IAsyncExternalPreview : IFeatures + { + /// + /// Method for opening/showing the preview. + /// + /// The file path to open the preview for + /// Whether to send a toast message notification on failure for the user + public Task OpenPreviewAsync(string path, bool sendFailToast = true); + + /// + /// Method for closing/hiding the preview. + /// + public Task ClosePreviewAsync(); + + /// + /// Method for switching the preview to the next file result. + /// This requires the external preview be already open/showing + /// + /// The file path to switch the preview for + /// Whether to send a toast message notification on failure for the user + public Task SwitchPreviewAsync(string path, bool sendFailToast = true); + + /// + /// Allows the preview plugin to override the AlwaysPreview setting. Typically useful if plugin's preview does not + /// fully work well with being shown together when the query window appears with results. + /// When AlwaysPreview setting is on and this is set to false, the preview will not be shown when query + /// window appears with results, instead the internal preview will be shown. + /// + /// + public bool AllowAlwaysPreview(); + } +} diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index ea79386b3..9b42b1021 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -270,12 +270,12 @@ namespace Flow.Launcher.Plugin /// /// Full image used for preview panel /// - public string PreviewImagePath { get; set; } + public string PreviewImagePath { get; set; } = null; /// /// Determines if the preview image should occupy the full width of the preview panel. /// - public bool IsMedia { get; set; } + public bool IsMedia { get; set; } = false; /// /// Result description text that is shown at the bottom of the preview panel. @@ -283,12 +283,17 @@ namespace Flow.Launcher.Plugin /// /// When a value is not set, the will be used. /// - public string Description { get; set; } + public string Description { get; set; } = null; /// /// Delegate to get the preview panel's image /// - public IconDelegate PreviewDelegate { get; set; } + public IconDelegate PreviewDelegate { get; set; } = null; + + /// + /// File path of the result. For third-party programs providing external preview. + /// + public string FilePath { get; set; } = null; /// /// Default instance of @@ -299,6 +304,7 @@ namespace Flow.Launcher.Plugin Description = null, IsMedia = false, PreviewDelegate = null, + FilePath = null, }; } } diff --git a/Flow.Launcher/Images/Error.png b/Flow.Launcher/Images/Error.png new file mode 100644 index 000000000..4bdcd80f9 Binary files /dev/null and b/Flow.Launcher/Images/Error.png differ diff --git a/Flow.Launcher/Images/Exclamation.png b/Flow.Launcher/Images/Exclamation.png new file mode 100644 index 000000000..a9d99362c Binary files /dev/null and b/Flow.Launcher/Images/Exclamation.png differ diff --git a/Flow.Launcher/Images/Information.png b/Flow.Launcher/Images/Information.png new file mode 100644 index 000000000..779e22dc1 Binary files /dev/null and b/Flow.Launcher/Images/Information.png differ diff --git a/Flow.Launcher/Images/Question.png b/Flow.Launcher/Images/Question.png new file mode 100644 index 000000000..6ca093f6d Binary files /dev/null and b/Flow.Launcher/Images/Question.png differ diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 700e60933..3844ccf11 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -189,6 +189,8 @@ Custom Clock Date + This theme supports two(light/dark) modes. + This theme supports Blur Transparent Background. @@ -213,6 +215,7 @@ Cycle Previous Query Cycle Next Query Open Context Menu + Open Native Context Menu Open Setting Window Copy File Path Toggle Game Mode @@ -357,6 +360,9 @@ Cancel Reset Delete + OK + Yes + No Version diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index 3686f348d..b312240d6 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -427,7 +427,7 @@ VerticalAlignment="Stretch" Background="Transparent" ShowsPreview="True" - Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}"> + Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}"> @@ -439,7 +439,7 @@ Grid.Column="2" VerticalAlignment="Stretch" Style="{DynamicResource PreviewArea}" - Visibility="{Binding PreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}"> + Visibility="{Binding InternalPreviewVisible, Converter={StaticResource BoolToVisibilityConverter}}"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +