mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Support installing from local path
This commit is contained in:
parent
f9e7b82b15
commit
248b098e54
4 changed files with 102 additions and 1 deletions
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
|
|
@ -633,6 +634,42 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
}
|
||||
|
||||
public static async Task InstallPluginAndCheckRestartAsync(string filePath)
|
||||
{
|
||||
UserPlugin plugin;
|
||||
try
|
||||
{
|
||||
using ZipArchive archive = ZipFile.OpenRead(filePath);
|
||||
var pluginJsonPath = archive.Entries.FirstOrDefault(x => x.Name == "plugin.json") ??
|
||||
throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
|
||||
var pluginJsonEntry = archive.GetEntry(pluginJsonPath.ToString()) ??
|
||||
throw new FileNotFoundException("The zip file does not contain a plugin.json file.");
|
||||
|
||||
using Stream stream = pluginJsonEntry.Open();
|
||||
plugin = JsonSerializer.Deserialize<UserPlugin>(stream);
|
||||
plugin.IcoPath = "Images\\zipfolder.png";
|
||||
plugin.LocalInstallPath = filePath;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
API.LogException(ClassName, "Failed to validate zip file", e);
|
||||
API.ShowMsgError(API.GetTranslation("ZipFileNotHavePluginJson"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (FlowSettings.ShowUnknownSourceWarning)
|
||||
{
|
||||
if (!InstallSourceKnown(plugin.Website)
|
||||
&& API.ShowMsgBox(string.Format(
|
||||
API.GetTranslation("InstallFromUnknownSourceSubtitle"), Environment.NewLine),
|
||||
API.GetTranslation("InstallFromUnknownSourceTitle"),
|
||||
MessageBoxButton.YesNo) == MessageBoxResult.No)
|
||||
return;
|
||||
}
|
||||
|
||||
await InstallPluginAndCheckRestartAsync(plugin);
|
||||
}
|
||||
|
||||
public static async Task UninstallPluginAndCheckRestartAsync(PluginMetadata oldPlugin)
|
||||
{
|
||||
if (API.ShowMsgBox(
|
||||
|
|
@ -913,6 +950,24 @@ namespace Flow.Launcher.Core.Plugin
|
|||
}
|
||||
}
|
||||
|
||||
private static bool InstallSourceKnown(string url)
|
||||
{
|
||||
var pieces = url.Split('/');
|
||||
|
||||
if (pieces.Length < 4)
|
||||
return false;
|
||||
|
||||
var author = pieces[3];
|
||||
var acceptedSource = "https://github.com";
|
||||
var constructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
|
||||
|
||||
return url.StartsWith(acceptedSource) &&
|
||||
API.GetAllPlugins().Any(x =>
|
||||
!string.IsNullOrEmpty(x.Metadata.Website) &&
|
||||
x.Metadata.Website.StartsWith(constructedUrlPart)
|
||||
);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,6 +204,12 @@
|
|||
<system:String x:Key="UpdatePromptSubtitle">{0} by {1} {2}{2}Would you like to update this plugin?</system:String>
|
||||
<system:String x:Key="DownloadingPlugin">Downloading plugin</system:String>
|
||||
<system:String x:Key="AutoRestartAfterChange">Automatically restart after installing/uninstalling/updating plugins in plugin store</system:String>
|
||||
<system:String x:Key="ZipFileNotHavePluginJson">Zip file does not have a valid plugin.json configuration</system:String>
|
||||
<system:String x:Key="InstallFromUnknownSourceTitle">Installing from an unknown source</system:String>
|
||||
<system:String x:Key="InstallFromUnknownSourceSubtitle">This plugin is from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning in general section of setting window)</system:String>
|
||||
<system:String x:Key="ZipFiles">Zip files</system:String>
|
||||
<system:String x:Key="SelectZipFile">Please select zip file</system:String>
|
||||
<system:String x:Key="installLocalPluginTooltip">Install plugin from local path</system:String>
|
||||
|
||||
<!-- Setting Theme -->
|
||||
<system:String x:Key="theme">Theme</system:String>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Flow.Launcher.Core.Plugin;
|
||||
using Flow.Launcher.Plugin;
|
||||
using Flow.Launcher.ViewModel;
|
||||
|
||||
|
|
@ -96,6 +99,36 @@ public partial class SettingsPanePluginStoreViewModel : BaseModel
|
|||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task InstallPluginAsync()
|
||||
{
|
||||
var file = GetFileFromDialog(
|
||||
App.API.GetTranslation("SelectZipFile"),
|
||||
$"{App.API.GetTranslation("ZipFiles")} (*.zip)|*.zip");
|
||||
|
||||
if (!string.IsNullOrEmpty(file))
|
||||
await PluginManager.InstallPluginAndCheckRestartAsync(file);
|
||||
}
|
||||
|
||||
private static string GetFileFromDialog(string title, string filter = "")
|
||||
{
|
||||
var dlg = new OpenFileDialog
|
||||
{
|
||||
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads",
|
||||
Multiselect = false,
|
||||
CheckFileExists = true,
|
||||
CheckPathExists = true,
|
||||
Title = title,
|
||||
Filter = filter
|
||||
};
|
||||
|
||||
return dlg.ShowDialog() switch
|
||||
{
|
||||
DialogResult.OK => dlg.FileName,
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
public bool SatisfiesFilter(PluginStoreItemViewModel plugin)
|
||||
{
|
||||
// Check plugin language
|
||||
|
|
|
|||
|
|
@ -92,6 +92,13 @@
|
|||
</ui:MenuFlyout>
|
||||
</ui:FlyoutService.Flyout>
|
||||
</Button>
|
||||
<Button
|
||||
Height="34"
|
||||
Margin="0 0 10 0"
|
||||
Command="{Binding InstallPluginCommand}"
|
||||
ToolTip="{DynamicResource installLocalPluginTooltip}">
|
||||
<ui:FontIcon FontSize="14" Glyph="" />
|
||||
</Button>
|
||||
<TextBox
|
||||
Name="PluginStoreFilterTextbox"
|
||||
Width="150"
|
||||
|
|
|
|||
Loading…
Reference in a new issue