Skip to content

Commit b826090

Browse files
committed
Merge remote-tracking branch 'origin/dev' into GlobalHotkeyRefactor
2 parents 84fed73 + 5803cbe commit b826090

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+9278
-3698
lines changed

Flow.Launcher.Core/Plugin/PluginConfig.cs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.IO;
@@ -45,8 +45,56 @@ public static List<PluginMetadata> Parse(string[] pluginDirectories)
4545
}
4646
}
4747
}
48-
49-
return allPluginMetadata;
48+
49+
(List<PluginMetadata> uniqueList, List<PluginMetadata> duplicateList) = GetUniqueLatestPluginMetadata(allPluginMetadata);
50+
51+
duplicateList
52+
.ForEach(
53+
x => Log.Warn("PluginConfig",
54+
string.Format("Duplicate plugin name: {0}, id: {1}, version: {2} " +
55+
"not loaded due to version not the highest of the duplicates",
56+
x.Name, x.ID, x.Version),
57+
"GetUniqueLatestPluginMetadata"));
58+
59+
return uniqueList;
60+
}
61+
62+
internal static (List<PluginMetadata>, List<PluginMetadata>) GetUniqueLatestPluginMetadata(List<PluginMetadata> allPluginMetadata)
63+
{
64+
var duplicate_list = new List<PluginMetadata>();
65+
var unique_list = new List<PluginMetadata>();
66+
67+
var duplicateGroups = allPluginMetadata.GroupBy(x => x.ID).Where(g => g.Count() > 1).Select(y => y).ToList();
68+
69+
foreach (var metadata in allPluginMetadata)
70+
{
71+
var duplicatesExist = false;
72+
foreach (var group in duplicateGroups)
73+
{
74+
if (metadata.ID == group.Key)
75+
{
76+
duplicatesExist = true;
77+
78+
// If metadata's version greater than each duplicate's version, CompareTo > 0
79+
var count = group.Where(x => metadata.Version.CompareTo(x.Version) > 0).Count();
80+
81+
// Only add if the meatadata's version is the highest of all duplicates in the group
82+
if (count == group.Count() - 1)
83+
{
84+
unique_list.Add(metadata);
85+
}
86+
else
87+
{
88+
duplicate_list.Add(metadata);
89+
}
90+
}
91+
}
92+
93+
if (!duplicatesExist)
94+
unique_list.Add(metadata);
95+
}
96+
97+
return (unique_list, duplicate_list);
5098
}
5199

52100
private static PluginMetadata GetPluginMetadata(string pluginDirectory)

Flow.Launcher.Infrastructure/Constant.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,16 @@ public static class Constant
3535

3636
public const string DefaultTheme = "Win11Light";
3737

38+
public const string Light = "Light";
39+
public const string Dark = "Dark";
40+
public const string System = "System";
41+
3842
public const string Themes = "Themes";
43+
public const string Settings = "Settings";
44+
public const string Logs = "Logs";
3945

4046
public const string Website = "https://flow-launcher.github.io";
47+
public const string GitHub = "https://github.com/Flow-Launcher/Flow.Launcher";
48+
public const string Docs = "https://flow-launcher.github.io/docs";
4149
}
4250
}

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class Settings : BaseModel
1515
private string language = "en";
1616
public string Hotkey { get; set; } = $"{KeyConstant.Alt} + {KeyConstant.Space}";
1717
public string OpenResultModifiers { get; set; } = KeyConstant.Alt;
18+
public string DarkMode { get; set; } = "System";
1819
public bool ShowOpenResultHotkey { get; set; } = true;
1920
public double WindowSize { get; set; } = 580;
2021

@@ -82,6 +83,8 @@ public CustomExplorerViewModel CustomExplorer
8283
}
8384
};
8485

86+
public bool UseAnimation { get; set; } = true;
87+
public bool UseSound { get; set; } = true;
8588

8689
/// <summary>
8790
/// when false Alphabet static service will always return empty results
@@ -163,4 +166,11 @@ public enum LastQueryMode
163166
Empty,
164167
Preserved
165168
}
169+
170+
public enum DarkMode
171+
{
172+
System,
173+
Light,
174+
Dark
175+
}
166176
}

Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ public interface IPublicAPI
2929
/// </summary>
3030
void RestartApp();
3131

32+
/// <summary>
33+
/// Run a shell command
34+
/// </summary>
35+
/// <param name="cmd">The command or program to run</param>
36+
/// <param name="filename">the shell type to run, e.g. powershell.exe</param>
37+
/// <exception cref="FileNotFoundException">Thrown when unable to find the file specified in the command </exception>
38+
/// <exception cref="Win32Exception">Thrown when error occurs during the execution of the command </exception>
39+
void ShellRun(string cmd, string filename = "cmd.exe");
40+
3241
/// <summary>
3342
/// Save everything, all of Flow Launcher and plugins' data and settings
3443
/// </summary>

Flow.Launcher.Plugin/Result.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public string IcoPath
5050
/// <summary>
5151
/// Delegate to Get Image Source
5252
/// </summary>
53-
public IconDelegate Icon { get; set; }
53+
public IconDelegate Icon;
5454

5555
/// <summary>
5656
/// Information for Glyph Icon

Flow.Launcher.Plugin/SharedCommands/ShellCommand.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Linq;
@@ -60,17 +60,39 @@ private static string GetWindowTitle(IntPtr hwnd)
6060
return sb.ToString();
6161
}
6262

63-
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "")
63+
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "", bool createNoWindow = false)
6464
{
6565
var info = new ProcessStartInfo
6666
{
6767
FileName = fileName,
6868
WorkingDirectory = workingDirectory,
6969
Arguments = arguments,
70-
Verb = verb
70+
Verb = verb,
71+
CreateNoWindow = createNoWindow
7172
};
7273

7374
return info;
7475
}
76+
77+
/// <summary>
78+
/// Runs a windows command using the provided ProcessStartInfo
79+
/// </summary>
80+
/// <exception cref="FileNotFoundException">Thrown when unable to find the file specified in the command </exception>
81+
/// <exception cref="Win32Exception">Thrown when error occurs during the execution of the command </exception>
82+
public static void Execute(ProcessStartInfo info)
83+
{
84+
Execute(Process.Start, info);
85+
}
86+
87+
/// <summary>
88+
/// Runs a windows command using the provided ProcessStartInfo using a custom execute command function
89+
/// </summary>
90+
/// <param name="Func startProcess">allows you to pass in a custom command execution function</param>
91+
/// <exception cref="FileNotFoundException">Thrown when unable to find the file specified in the command </exception>
92+
/// <exception cref="Win32Exception">Thrown when error occurs during the execution of the command </exception>
93+
public static void Execute(Func<ProcessStartInfo, Process> startProcess, ProcessStartInfo info)
94+
{
95+
startProcess(info);
96+
}
7597
}
7698
}

Flow.Launcher.Test/PluginLoadTest.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using NUnit.Framework;
2+
using Flow.Launcher.Core.Plugin;
3+
using Flow.Launcher.Plugin;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
7+
namespace Flow.Launcher.Test
8+
{
9+
[TestFixture]
10+
class PluginLoadTest
11+
{
12+
[Test]
13+
public void GivenDuplicatePluginMetadatasWhenLoadedThenShouldReturnOnlyUniqueList()
14+
{
15+
// Given
16+
var duplicateList = new List<PluginMetadata>
17+
{
18+
new PluginMetadata
19+
{
20+
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
21+
Version = "1.0.0"
22+
},
23+
new PluginMetadata
24+
{
25+
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
26+
Version = "1.0.1"
27+
},
28+
new PluginMetadata
29+
{
30+
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
31+
Version = "1.0.2"
32+
},
33+
new PluginMetadata
34+
{
35+
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
36+
Version = "1.0.0"
37+
},
38+
new PluginMetadata
39+
{
40+
ID = "CEA0TYUC6D3B4085823D60DC76F28855",
41+
Version = "1.0.0"
42+
},
43+
new PluginMetadata
44+
{
45+
ID = "ABC0TYUC6D3B7855823D60DC76F28855",
46+
Version = "1.0.0"
47+
},
48+
new PluginMetadata
49+
{
50+
ID = "ABC0TYUC6D3B7855823D60DC76F28855",
51+
Version = "1.0.0"
52+
}
53+
};
54+
55+
// When
56+
(var unique, var duplicates) = PluginConfig.GetUniqueLatestPluginMetadata(duplicateList);
57+
58+
// Then
59+
Assert.True(unique.FirstOrDefault().ID == "CEA0TYUC6D3B4085823D60DC76F28855" && unique.FirstOrDefault().Version == "1.0.2");
60+
Assert.True(unique.Count() == 1);
61+
62+
Assert.False(duplicates.Any(x => x.Version == "1.0.2" && x.ID == "CEA0TYUC6D3B4085823D60DC76F28855"));
63+
Assert.True(duplicates.Count() == 6);
64+
}
65+
66+
[Test]
67+
public void GivenDuplicatePluginMetadatasWithNoUniquePluginWhenLoadedThenShouldReturnEmptyList()
68+
{
69+
// Given
70+
var duplicateList = new List<PluginMetadata>
71+
{
72+
new PluginMetadata
73+
{
74+
ID = "CEA0TYUC6D3B7855823D60DC76F28855",
75+
Version = "1.0.0"
76+
},
77+
new PluginMetadata
78+
{
79+
ID = "CEA0TYUC6D3B7855823D60DC76F28855",
80+
Version = "1.0.0"
81+
}
82+
};
83+
84+
// When
85+
(var unique, var duplicates) = PluginConfig.GetUniqueLatestPluginMetadata(duplicateList);
86+
87+
// Then
88+
Assert.True(unique.Count() == 0);
89+
Assert.True(duplicates.Count() == 2);
90+
}
91+
}
92+
}

Flow.Launcher.Test/Plugins/PluginInitTest.cs

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)