add backwards compatibility with Everything plugin

This commit is contained in:
Jeremy Wu 2021-06-21 12:34:07 +10:00
parent e6db8b85e8
commit 7319133ae8
8 changed files with 130 additions and 8 deletions

View file

@ -48,9 +48,14 @@ namespace Flow.Launcher.Core.Plugin
{
foreach (var plugin in AllPlugins)
{
var savable = plugin.Plugin as ISavable;
var savable = plugin.Plugin as ISettingsSavable;
savable?.Save();
}
// Everything plugin
var savableEverything = AllPlugins.FirstOrDefault(x => x.Metadata.ID == "D2D2C23B084D411DB66FE0C79D6C2A6E")?.Plugin as ISavable;
savableEverything?.Save();
API.SavePluginSettings();
}

View file

@ -0,0 +1,11 @@
namespace Flow.Launcher.Infrastructure.Storage
{
/// <summary>
/// Save plugin settings/cache,
/// todo should be merged into a abstract class intead of seperate interface
/// </summary>
public interface ISavable
{
void Save();
}
}

View file

@ -87,4 +87,94 @@ namespace Flow.Launcher.Infrastructure.Storage
File.WriteAllText(FilePath, serialized);
}
}
public class JsonStrorage<T> where T : new()
{
private readonly JsonSerializerOptions _serializerSettings;
private T _data;
// need a new directory name
public const string DirectoryName = "Settings";
public const string FileSuffix = ".json";
public string FilePath { get; set; }
public string DirectoryPath { get; set; }
internal JsonStrorage()
{
// use property initialization instead of DefaultValueAttribute
// easier and flexible for default value of object
_serializerSettings = new JsonSerializerOptions
{
IgnoreNullValues = false
};
}
public T Load()
{
if (File.Exists(FilePath))
{
var searlized = File.ReadAllText(FilePath);
if (!string.IsNullOrWhiteSpace(searlized))
{
Deserialize(searlized);
}
else
{
LoadDefault();
}
}
else
{
LoadDefault();
}
return _data.NonNull();
}
private void Deserialize(string searlized)
{
try
{
_data = JsonSerializer.Deserialize<T>(searlized, _serializerSettings);
}
catch (JsonException e)
{
LoadDefault();
Log.Exception($"|JsonStrorage.Deserialize|Deserialize error for json <{FilePath}>", e);
}
if (_data == null)
{
LoadDefault();
}
}
private void LoadDefault()
{
if (File.Exists(FilePath))
{
BackupOriginFile();
}
_data = new T();
Save();
}
private void BackupOriginFile()
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.CurrentUICulture);
var directory = Path.GetDirectoryName(FilePath).NonNull();
var originName = Path.GetFileNameWithoutExtension(FilePath);
var backupName = $"{originName}-{timestamp}{FileSuffix}";
var backupPath = Path.Combine(directory, backupName);
File.Copy(FilePath, backupPath, true);
// todo give user notification for the backup process
}
public void Save()
{
string serialized = JsonSerializer.Serialize(_data, new JsonSerializerOptions() { WriteIndented = true });
File.WriteAllText(FilePath, serialized);
}
}
}

View file

@ -3,9 +3,9 @@ using Flow.Launcher.Infrastructure.UserSettings;
namespace Flow.Launcher.Infrastructure.Storage
{
public class PluginJsonStorage<T> :JsonStorage<T> where T : new()
public class PluginJsonSettingStorage<T> :JsonStorage<T> where T : new()
{
public PluginJsonStorage()
public PluginJsonSettingStorage()
{
// C# related, add python related below
var dataType = typeof(T);
@ -16,9 +16,25 @@ namespace Flow.Launcher.Infrastructure.Storage
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
}
public PluginJsonStorage(T data) : this()
public PluginJsonSettingStorage(T data) : this()
{
_data = data;
}
}
public class PluginJsonStorage<T> : JsonStrorage<T> where T : new()
{
public PluginJsonStorage()
{
// C# releated, add python releated below
var dataType = typeof(T);
var assemblyName = typeof(T).Assembly.GetName().Name;
DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, assemblyName);
Helper.ValidateDirectory(DirectoryPath);
FilePath = Path.Combine(DirectoryPath, $"{dataType.Name}{FileSuffix}");
}
}
}

View file

@ -5,7 +5,7 @@
/// Otherwise if LoadSettingJsonStorage or SaveSettingJsonStorage has been callded,
/// plugin settings will be automatically saved (see Flow.Launcher/PublicAPIInstance.SavePluginSettings) by Flow
/// </summary>
public interface ISavable
public interface ISettingsSavable
{
void Save();
}

View file

@ -177,7 +177,7 @@ namespace Flow.Launcher
public void SaveJsonStorage<T>(T settings) where T : new()
{
var type = typeof(T);
_pluginJsonStorages[type] = new PluginJsonStorage<T>(settings);
_pluginJsonStorages[type] = new PluginJsonSettingStorage<T>(settings);
((PluginJsonStorage<T>) _pluginJsonStorages[type]).Save();
}

View file

@ -23,7 +23,7 @@ using System.Threading.Channels;
namespace Flow.Launcher.ViewModel
{
public class MainViewModel : BaseModel, ISavable
public class MainViewModel : BaseModel, ISettingsSavable
{
#region Private Fields

View file

@ -13,7 +13,7 @@ using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
namespace Flow.Launcher.Plugin.Program
{
public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable
public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISettingsSavable, IAsyncReloadable
{
internal static Win32[] _win32s { get; set; }
internal static UWP.Application[] _uwps { get; set; }