diff --git a/.cm/gitstream.cm b/.cm/gitstream.cm new file mode 100644 index 000000000..fcf01c0fe --- /dev/null +++ b/.cm/gitstream.cm @@ -0,0 +1,75 @@ +# -*- mode: yaml -*- +# This example configuration for provides basic automations to get started with gitStream. +# View the gitStream quickstart for more examples: https://docs.gitstream.cm/examples/ +manifest: + version: 1.0 + + +automations: + # Add a label that indicates how many minutes it will take to review the PR. + estimated_time_to_review: + if: + - true + run: + - action: add-label@v1 + args: + label: "{{ calc.etr }} min review" + color: {{ colors.red if (calc.etr >= 20) else ( colors.yellow if (calc.etr >= 5) else colors.green ) }} + # Post a comment that lists the best experts for the files that were modified. + explain_code_experts: + if: + - true + run: + - action: explain-code-experts@v1 + args: + gt: 10 + # Post a comment that indicates what percentage of the PR is new code. + percent_new_code: + if: + - true + run: + - action: add-comment@v1 + args: + comment: | + This PR is {{ changes.ratio }}% new code. + # Post a comment that request changes for a PR that contains a TODO statement. + review_todo_comments: + if: + - {{ source.diff.files | matchDiffLines(regex=r/^[+].*(TODO)|(todo)/) | some }} + run: + - action: request-changes@v1 + args: + comment: | + This PR contains a TODO statement. Please check to see if they should be removed. + # Post a comment that request a before and after screenshot + request_screenshot: + # Triggered for PRs that lack an image file or link to an image in the PR description + if: + - {{ not (has.screenshot_link or has.image_uploaded) }} + run: + - action: add-comment@v1 + args: + comment: | + Be a legend :trophy: by adding a before and after screenshot of the changes you made, especially if they are around UI/UX. + + +# +----------------------------------------------------------------------------+ +# | Custom Expressions | +# | https://docs.gitstream.cm/how-it-works/#custom-expressions | +# +----------------------------------------------------------------------------+ + +calc: + etr: {{ branch | estimatedReviewTime }} + +colors: + red: 'b60205' + yellow: 'fbca04' + green: '0e8a16' + +changes: + # Sum all the lines added/edited in the PR + additions: {{ branch.diff.files_metadata | map(attr='additions') | sum }} + # 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 diff --git a/.github/workflows/gitstream.yml b/.github/workflows/gitstream.yml new file mode 100644 index 000000000..0916572df --- /dev/null +++ b/.github/workflows/gitstream.yml @@ -0,0 +1,49 @@ +# Code generated by gitStream GitHub app - DO NOT EDIT + +name: gitStream workflow automation +run-name: | + /:\ gitStream: PR #${{ fromJSON(fromJSON(github.event.inputs.client_payload)).pullRequestNumber }} from ${{ github.event.inputs.full_repository }} + +on: + workflow_dispatch: + inputs: + client_payload: + description: The Client payload + required: true + full_repository: + description: the repository name include the owner in `owner/repo_name` format + required: true + head_ref: + description: the head sha + required: true + base_ref: + description: the base ref + required: true + installation_id: + description: the installation id + required: false + resolver_url: + description: the resolver url to pass results to + required: true + resolver_token: + description: Optional resolver token for resolver service + required: false + default: '' + +jobs: + gitStream: + timeout-minutes: 5 + runs-on: ubuntu-latest + name: gitStream workflow automation + steps: + - name: Evaluate Rules + uses: linear-b/gitstream-github-action@v2 + id: rules-engine + with: + full_repository: ${{ github.event.inputs.full_repository }} + head_ref: ${{ github.event.inputs.head_ref }} + base_ref: ${{ github.event.inputs.base_ref }} + client_payload: ${{ github.event.inputs.client_payload }} + installation_id: ${{ github.event.inputs.installation_id }} + resolver_url: ${{ github.event.inputs.resolver_url }} + resolver_token: ${{ github.event.inputs.resolver_token }} diff --git a/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs b/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs index a14baf271..bae263157 100644 --- a/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs +++ b/Flow.Launcher.Core/Plugin/ProcessStreamPluginV2.cs @@ -82,10 +82,10 @@ namespace Flow.Launcher.Core.Plugin public override async ValueTask DisposeAsync() { + await base.DisposeAsync(); ClientProcess.Kill(true); await ClientProcess.WaitForExitAsync(); ClientProcess.Dispose(); - await base.DisposeAsync(); } } } diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs index 61f0b18e0..c3a3e9891 100644 --- a/Flow.Launcher.Core/Resource/Theme.cs +++ b/Flow.Launcher.Core/Resource/Theme.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Xml; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls; @@ -17,6 +18,10 @@ namespace Flow.Launcher.Core.Resource { public class Theme { + private const string ThemeMetadataNamePrefix = "Name:"; + private const string ThemeMetadataIsDarkPrefix = "IsDark:"; + private const string ThemeMetadataHasBlurPrefix = "HasBlur:"; + private const int ShadowExtraMargin = 32; private readonly List _themeDirectories = new List(); @@ -79,14 +84,14 @@ namespace Flow.Launcher.Core.Resource { if (string.IsNullOrEmpty(path)) throw new DirectoryNotFoundException("Theme path can't be found <{path}>"); - + // reload all resources even if the theme itself hasn't changed in order to pickup changes // to things like fonts UpdateResourceDictionary(GetResourceDictionary(theme)); - + Settings.Theme = theme; - + //always allow re-loading default theme, in case of failure of switching to a new theme from default theme if (_oldTheme != theme || theme == defaultTheme) { @@ -148,7 +153,7 @@ namespace Flow.Launcher.Core.Resource public ResourceDictionary GetResourceDictionary(string theme) { var dict = GetThemeResourceDictionary(theme); - + if (dict["QueryBoxStyle"] is Style queryBoxStyle && dict["QuerySuggestionBoxStyle"] is Style querySuggestionBoxStyle) { @@ -187,7 +192,7 @@ namespace Flow.Launcher.Core.Resource Setter[] setters = { fontFamily, fontStyle, fontWeight, fontStretch }; Array.ForEach( - new[] { resultItemStyle, resultItemSelectedStyle, resultHotkeyItemStyle, resultHotkeyItemSelectedStyle }, o + new[] { resultItemStyle, resultItemSelectedStyle, resultHotkeyItemStyle, resultHotkeyItemSelectedStyle }, o => Array.ForEach(setters, p => o.Setters.Add(p))); } @@ -219,17 +224,53 @@ namespace Flow.Launcher.Core.Resource return GetResourceDictionary(Settings.Theme); } - public List LoadAvailableThemes() + public List LoadAvailableThemes() { - List themes = new List(); + List themes = new List(); foreach (var themeDirectory in _themeDirectories) { - themes.AddRange( - Directory.GetFiles(themeDirectory) - .Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml")) - .ToList()); + var filePaths = Directory + .GetFiles(themeDirectory) + .Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml")) + .Select(GetThemeDataFromPath); + themes.AddRange(filePaths); } - return themes.OrderBy(o => o).ToList(); + + return themes.OrderBy(o => o.Name).ToList(); + } + + private ThemeData GetThemeDataFromPath(string path) + { + using var reader = XmlReader.Create(path); + reader.Read(); + + var extensionlessName = Path.GetFileNameWithoutExtension(path); + + if (reader.NodeType is not XmlNodeType.Comment) + return new ThemeData(extensionlessName, extensionlessName); + + var commentLines = reader.Value.Trim().Split('\n').Select(v => v.Trim()); + + var name = extensionlessName; + bool? isDark = null; + bool? hasBlur = null; + foreach (var line in commentLines) + { + if (line.StartsWith(ThemeMetadataNamePrefix, StringComparison.OrdinalIgnoreCase)) + { + name = line.Remove(0, ThemeMetadataNamePrefix.Length).Trim(); + } + else if (line.StartsWith(ThemeMetadataIsDarkPrefix, StringComparison.OrdinalIgnoreCase)) + { + isDark = bool.Parse(line.Remove(0, ThemeMetadataIsDarkPrefix.Length).Trim()); + } + else if (line.StartsWith(ThemeMetadataHasBlurPrefix, StringComparison.OrdinalIgnoreCase)) + { + hasBlur = bool.Parse(line.Remove(0, ThemeMetadataHasBlurPrefix.Length).Trim()); + } + } + + return new ThemeData(extensionlessName, name, isDark, hasBlur); } private string GetThemePath(string themeName) @@ -407,5 +448,7 @@ namespace Flow.Launcher.Core.Resource Marshal.FreeHGlobal(accentPtr); } #endregion + + public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, bool? HasBlur = null); } } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 626ca31c2..0c7de10fd 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -55,7 +55,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings OnPropertyChanged(nameof(MaxResultsToShow)); } } - public bool UseDropShadowEffect { get; set; } = false; + public bool UseDropShadowEffect { get; set; } = true; /* Appearance Settings. It should be separated from the setting later.*/ public double WindowHeightSize { get; set; } = 42; diff --git a/Flow.Launcher/App.xaml b/Flow.Launcher/App.xaml index 76a613c3f..13e943c95 100644 --- a/Flow.Launcher/App.xaml +++ b/Flow.Launcher/App.xaml @@ -25,7 +25,7 @@ - + diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 848c52f1f..0d982c5a4 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -4,7 +4,7 @@ WinExe net7.0-windows10.0.19041.0 true - true + false Flow.Launcher.App Resources\app.ico app.manifest diff --git a/Flow.Launcher/Images/app_error.png b/Flow.Launcher/Images/app_error.png index 70599f504..a5664e263 100644 Binary files a/Flow.Launcher/Images/app_error.png and b/Flow.Launcher/Images/app_error.png differ diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 28b516757..83831a398 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -57,7 +57,7 @@ Select last Query Empty last Query Fixed Window Height - The window height will not be resizeable by dragging + The window height is not adjustable by dragging. Maximum results shown You can also quickly adjust this by using CTRL+Plus and CTRL+Minus. Ignore hotkeys in fullscreen mode @@ -75,6 +75,7 @@ Auto Update Select Hide Flow Launcher on startup + Flow Launcher search window is hidden in the tray after starting up. Hide tray icon When the icon is hidden from the tray, the Settings menu can be opened by right-clicking on the search window. Query Search Precision @@ -279,6 +280,9 @@ Clear Logs Are you sure you want to delete all logs? Wizard + User Data Location + User settings and installed plugins are saved in the user data folder. This location may vary depending on whether it's in portable mode or not. + Open Folder Select File Manager diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index bd6b13934..b312240d6 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -380,24 +380,24 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - + - - - - + + + + + + + - - - + + + + - - - - - - - - - - - - + + + + + - + diff --git a/Flow.Launcher/Resources/CustomControlTemplate.xaml b/Flow.Launcher/Resources/CustomControlTemplate.xaml index a53e61f8c..3d599aaed 100644 --- a/Flow.Launcher/Resources/CustomControlTemplate.xaml +++ b/Flow.Launcher/Resources/CustomControlTemplate.xaml @@ -74,7 +74,8 @@ - + + @@ -1642,6 +1643,80 @@ + + 0:0:0.033 @@ -1657,7 +1732,7 @@ - + diff --git a/Flow.Launcher/Resources/Dark.xaml b/Flow.Launcher/Resources/Dark.xaml index a910108e8..ed031c939 100644 --- a/Flow.Launcher/Resources/Dark.xaml +++ b/Flow.Launcher/Resources/Dark.xaml @@ -7,16 +7,17 @@ xmlns:sys="clr-namespace:System;assembly=mscorlib"> - + - + + #198F8F8F @@ -1605,18 +1606,23 @@ - - + + - - - + + + + + + + + True False diff --git a/Flow.Launcher/Resources/Light.xaml b/Flow.Launcher/Resources/Light.xaml index 906430343..8fe84588f 100644 --- a/Flow.Launcher/Resources/Light.xaml +++ b/Flow.Launcher/Resources/Light.xaml @@ -7,16 +7,17 @@ xmlns:sys="clr-namespace:System;assembly=mscorlib"> - + - + + #198F8F8F @@ -1608,9 +1609,11 @@ - - + + + + True diff --git a/Flow.Launcher/Resources/SettingWindowStyle.xaml b/Flow.Launcher/Resources/SettingWindowStyle.xaml index 2c73094c7..41c11e346 100644 --- a/Flow.Launcher/Resources/SettingWindowStyle.xaml +++ b/Flow.Launcher/Resources/SettingWindowStyle.xaml @@ -25,7 +25,7 @@ + @@ -123,8 +164,8 @@ x:Name="Spacer" Width="Auto" Height="Auto" - Margin="0,10,5,0" - Padding="0,0,0,0" + Margin="0 10 5 0" + Padding="0 0 0 0" BorderBrush="Transparent" BorderThickness="0"> @@ -180,7 +221,7 @@ Grid.Column="0" Width="4" Height="18" - Margin="0,11,0,11" + Margin="0 11 0 11" Fill="{DynamicResource ToggleSwitchFillOn}" RadiusX="2" RadiusY="2" @@ -188,7 +229,7 @@ - + - + @@ -255,7 +296,7 @@ - + @@ -267,7 +308,7 @@ - + @@ -284,10 +325,10 @@ + - - - - - - - - - - - - - - + SelectedValue="{Binding SelectedTheme}"> + + + + + + + + + + + + + + + + + + - - - + + - + - + - + - +