Skip to content

Commit be8bb8b

Browse files
authored
Merge pull request #427 from Flow-Launcher/MigrateDirectPluginJsonStorage
Use API call to save instead of direct call
2 parents 7092263 + 1e687a2 commit be8bb8b

File tree

28 files changed

+126
-198
lines changed

28 files changed

+126
-198
lines changed

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public static void Save()
5151
var savable = plugin.Plugin as ISavable;
5252
savable?.Save();
5353
}
54+
API.SavePluginSettings();
5455
}
5556

5657
public static async Task ReloadData()

Flow.Launcher.Infrastructure/Storage/FlowLauncherJsonStorage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Flow.Launcher.Infrastructure.Storage
1010
{
11-
public class FlowLauncherJsonStorage<T> : JsonStrorage<T> where T : new()
11+
public class FlowLauncherJsonStorage<T> : JsonStorage<T> where T : new()
1212
{
1313
public FlowLauncherJsonStorage()
1414
{

Flow.Launcher.Infrastructure/Storage/JsonStorage.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Flow.Launcher.Infrastructure.Storage
99
/// <summary>
1010
/// Serialize object using json format.
1111
/// </summary>
12-
public class JsonStrorage<T> where T : new()
12+
public class JsonStorage<T> where T : new()
1313
{
1414
protected T _data;
1515
// need a new directory name
@@ -23,10 +23,10 @@ public T Load()
2323
{
2424
if (File.Exists(FilePath))
2525
{
26-
var searlized = File.ReadAllText(FilePath);
27-
if (!string.IsNullOrWhiteSpace(searlized))
26+
var serialized = File.ReadAllText(FilePath);
27+
if (!string.IsNullOrWhiteSpace(serialized))
2828
{
29-
Deserialize(searlized);
29+
Deserialize(serialized);
3030
}
3131
else
3232
{
@@ -40,16 +40,16 @@ public T Load()
4040
return _data.NonNull();
4141
}
4242

43-
private void Deserialize(string searlized)
43+
private void Deserialize(string serialized)
4444
{
4545
try
4646
{
47-
_data = JsonSerializer.Deserialize<T>(searlized);
47+
_data = JsonSerializer.Deserialize<T>(serialized);
4848
}
4949
catch (JsonException e)
5050
{
5151
LoadDefault();
52-
Log.Exception($"|JsonStrorage.Deserialize|Deserialize error for json <{FilePath}>", e);
52+
Log.Exception($"|JsonStorage.Deserialize|Deserialize error for json <{FilePath}>", e);
5353
}
5454

5555
if (_data == null)

Flow.Launcher.Infrastructure/Storage/PluginJsonStorage.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
namespace Flow.Launcher.Infrastructure.Storage
55
{
6-
public class PluginJsonStorage<T> :JsonStrorage<T> where T : new()
6+
public class PluginJsonStorage<T> :JsonStorage<T> where T : new()
77
{
88
public PluginJsonStorage()
99
{
10-
// C# releated, add python releated below
10+
// C# related, add python related below
1111
var dataType = typeof(T);
12-
var assemblyName = typeof(T).Assembly.GetName().Name;
12+
var assemblyName = dataType.Assembly.GetName().Name;
1313
DirectoryPath = Path.Combine(DataLocation.DataDirectory(), DirectoryName, Constant.Plugins, assemblyName);
1414
Helper.ValidateDirectory(DirectoryPath);
1515

Flow.Launcher.Plugin/IPublicAPI.cs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ public interface IPublicAPI
3030
void RestartApp();
3131

3232
/// <summary>
33-
/// Save all Flow Launcher settings
33+
/// Save everything, all of Flow Launcher and plugins' data and settings
3434
/// </summary>
3535
void SaveAppAllSettings();
3636

37+
/// <summary>
38+
/// Save all Flow's plugins settings
39+
/// </summary>
40+
void SavePluginSettings();
41+
3742
/// <summary>
3843
/// Reloads any Plugins that have the
3944
/// IReloadable implemented. It refeshes
@@ -165,33 +170,20 @@ public interface IPublicAPI
165170
void LogException(string className, string message, Exception e, [CallerMemberName] string methodName = "");
166171

167172
/// <summary>
168-
/// Load JsonStorage for current plugin. This is the method used to load settings from json in Flow
173+
/// Load JsonStorage for current plugin's setting. This is the method used to load settings from json in Flow.
174+
/// When the file is not exist, it will create a new instance for the specific type.
169175
/// </summary>
170176
/// <typeparam name="T">Type for deserialization</typeparam>
171177
/// <returns></returns>
172-
T LoadJsonStorage<T>() where T : new();
178+
T LoadSettingJsonStorage<T>() where T : new();
173179

174180
/// <summary>
175-
/// Save JsonStorage for current plugin. This is the method used to save settings to json in Flow.Launcher
181+
/// Save JsonStorage for current plugin's setting. This is the method used to save settings to json in Flow.Launcher
176182
/// This method will save the original instance loaded with LoadJsonStorage.
183+
/// This API call is for manually Save. Flow will automatically save all setting type that has called LoadSettingJsonStorage or SaveSettingJsonStorage previously.
177184
/// </summary>
178185
/// <typeparam name="T">Type for Serialization</typeparam>
179186
/// <returns></returns>
180-
void SaveJsonStorage<T>() where T : new();
181-
182-
/// <summary>
183-
/// Save JsonStorage for current plugin. This is the method used to save settings to json in Flow.Launcher
184-
/// This method will override the original class instance loaded from LoadJsonStorage
185-
/// </summary>
186-
/// <typeparam name="T">Type for Serialization</typeparam>
187-
/// <returns></returns>
188-
void SaveJsonStorage<T>(T settings) where T : new();
189-
190-
/// <summary>
191-
/// Backup the JsonStorage you loaded from LoadJsonStorage
192-
/// </summary>
193-
/// <typeparam name="T"></typeparam>
194-
/// <param name="settings"></param>
195-
void BackupJsonStorage<T>() where T : new();
187+
void SaveSettingJsonStorage<T>() where T : new();
196188
}
197189
}

Flow.Launcher.Plugin/Interfaces/ISavable.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
namespace Flow.Launcher.Plugin
22
{
33
/// <summary>
4-
/// Save plugin settings/cache,
5-
/// todo should be merged into a abstract class intead of seperate interface
4+
/// Save addtional plugin data. Inherit this interface if additional data e.g. cache needs to be saved,
5+
/// Otherwise if LoadSettingJsonStorage or SaveSettingJsonStorage has been callded,
6+
/// plugin settings will be automatically saved (see Flow.Launcher/PublicAPIInstance.SavePluginSettings) by Flow
67
/// </summary>
78
public interface ISavable
89
{

Flow.Launcher/PublicAPIInstance.cs

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,25 @@ public void RestartApp()
7676

7777
public void SaveAppAllSettings()
7878
{
79+
SavePluginSettings();
7980
_mainVM.Save();
8081
_settingsVM.Save();
81-
PluginManager.Save();
8282
ImageLoader.Save();
8383
}
8484

8585
public Task ReloadAllPluginData() => PluginManager.ReloadData();
8686

87-
public void ShowMsgError(string title, string subTitle = "") => ShowMsg(title, subTitle, Constant.ErrorIcon, true);
87+
public void ShowMsgError(string title, string subTitle = "") =>
88+
ShowMsg(title, subTitle, Constant.ErrorIcon, true);
8889

89-
public void ShowMsg(string title, string subTitle = "", string iconPath = "") => ShowMsg(title, subTitle, iconPath, true);
90+
public void ShowMsg(string title, string subTitle = "", string iconPath = "") =>
91+
ShowMsg(title, subTitle, iconPath, true);
9092

9193
public void ShowMsg(string title, string subTitle, string iconPath, bool useMainWindowAsOwner = true)
9294
{
9395
Application.Current.Dispatcher.Invoke(() =>
9496
{
95-
var msg = useMainWindowAsOwner ? new Msg { Owner = Application.Current.MainWindow } : new Msg();
97+
var msg = useMainWindowAsOwner ? new Msg {Owner = Application.Current.MainWindow} : new Msg();
9698
msg.Show(title, subTitle, iconPath);
9799
});
98100
}
@@ -113,61 +115,70 @@ public void OpenSettingDialog()
113115

114116
public List<PluginPair> GetAllPlugins() => PluginManager.AllPlugins.ToList();
115117

116-
public MatchResult FuzzySearch(string query, string stringToCompare) => StringMatcher.FuzzySearch(query, stringToCompare);
118+
public MatchResult FuzzySearch(string query, string stringToCompare) =>
119+
StringMatcher.FuzzySearch(query, stringToCompare);
117120

118121
public Task<string> HttpGetStringAsync(string url, CancellationToken token = default) => Http.GetAsync(url);
119122

120-
public Task<Stream> HttpGetStreamAsync(string url, CancellationToken token = default) => Http.GetStreamAsync(url);
123+
public Task<Stream> HttpGetStreamAsync(string url, CancellationToken token = default) =>
124+
Http.GetStreamAsync(url);
121125

122-
public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, CancellationToken token = default) => Http.DownloadAsync(url, filePath, token);
126+
public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath,
127+
CancellationToken token = default) => Http.DownloadAsync(url, filePath, token);
123128

124-
public void AddActionKeyword(string pluginId, string newActionKeyword) => PluginManager.AddActionKeyword(pluginId, newActionKeyword);
129+
public void AddActionKeyword(string pluginId, string newActionKeyword) =>
130+
PluginManager.AddActionKeyword(pluginId, newActionKeyword);
125131

126-
public void RemoveActionKeyword(string pluginId, string oldActionKeyword) => PluginManager.RemoveActionKeyword(pluginId, oldActionKeyword);
132+
public void RemoveActionKeyword(string pluginId, string oldActionKeyword) =>
133+
PluginManager.RemoveActionKeyword(pluginId, oldActionKeyword);
127134

128-
public void LogDebug(string className, string message, [CallerMemberName] string methodName = "") => Log.Debug(className, message, methodName);
135+
public void LogDebug(string className, string message, [CallerMemberName] string methodName = "") =>
136+
Log.Debug(className, message, methodName);
129137

130-
public void LogInfo(string className, string message, [CallerMemberName] string methodName = "") => Log.Info(className, message, methodName);
138+
public void LogInfo(string className, string message, [CallerMemberName] string methodName = "") =>
139+
Log.Info(className, message, methodName);
131140

132-
public void LogWarn(string className, string message, [CallerMemberName] string methodName = "") => Log.Warn(className, message, methodName);
141+
public void LogWarn(string className, string message, [CallerMemberName] string methodName = "") =>
142+
Log.Warn(className, message, methodName);
133143

134-
public void LogException(string className, string message, Exception e, [CallerMemberName] string methodName = "") => Log.Exception(className, message, e, methodName);
144+
public void LogException(string className, string message, Exception e,
145+
[CallerMemberName] string methodName = "") => Log.Exception(className, message, e, methodName);
135146

136-
private readonly Dictionary<Type, dynamic> PluginJsonStorages = new Dictionary<Type, dynamic>();
147+
private readonly Dictionary<Type, object> _pluginJsonStorages = new();
137148

138-
public T LoadJsonStorage<T>() where T : new()
149+
public void SavePluginSettings()
139150
{
140-
var type = typeof(T);
141-
if (!PluginJsonStorages.ContainsKey(type))
142-
PluginJsonStorages[type] = new PluginJsonStorage<T>();
143-
144-
return PluginJsonStorages[type].Load();
151+
foreach (var value in _pluginJsonStorages.Values)
152+
{
153+
var method = value.GetType().GetMethod("Save");
154+
method?.Invoke(value, null);
155+
}
145156
}
146157

147-
public void SaveJsonStorage<T>() where T : new()
158+
public T LoadSettingJsonStorage<T>() where T : new()
148159
{
149160
var type = typeof(T);
150-
if (!PluginJsonStorages.ContainsKey(type))
151-
PluginJsonStorages[type] = new PluginJsonStorage<T>();
161+
if (!_pluginJsonStorages.ContainsKey(type))
162+
_pluginJsonStorages[type] = new PluginJsonStorage<T>();
152163

153-
PluginJsonStorages[type].Save();
164+
return ((PluginJsonStorage<T>) _pluginJsonStorages[type]).Load();
154165
}
155166

156-
public void SaveJsonStorage<T>(T settings) where T : new()
167+
public void SaveSettingJsonStorage<T>() where T : new()
157168
{
158169
var type = typeof(T);
159-
PluginJsonStorages[type] = new PluginJsonStorage<T>(settings);
170+
if (!_pluginJsonStorages.ContainsKey(type))
171+
_pluginJsonStorages[type] = new PluginJsonStorage<T>();
160172

161-
PluginJsonStorages[type].Save();
173+
((PluginJsonStorage<T>) _pluginJsonStorages[type]).Save();
162174
}
163175

164-
public void BackupJsonStorage<T>() where T : new()
176+
public void SaveJsonStorage<T>(T settings) where T : new()
165177
{
166178
var type = typeof(T);
167-
if (!PluginJsonStorages.ContainsKey(type))
168-
throw new InvalidOperationException("You haven't registered the JsonStorage for specific Type");
179+
_pluginJsonStorages[type] = new PluginJsonStorage<T>(settings);
169180

170-
PluginJsonStorages[type].BackupOriginFile();
181+
((PluginJsonStorage<T>) _pluginJsonStorages[type]).Save();
171182
}
172183

173184
public event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent;
@@ -180,11 +191,12 @@ private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, Spe
180191
{
181192
if (GlobalKeyboardEvent != null)
182193
{
183-
return GlobalKeyboardEvent((int)keyevent, vkcode, state);
194+
return GlobalKeyboardEvent((int) keyevent, vkcode, state);
184195
}
196+
185197
return true;
186198
}
187199

188200
#endregion
189201
}
190-
}
202+
}

Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,19 @@
1212

1313
namespace Flow.Launcher.Plugin.BrowserBookmark
1414
{
15-
public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, ISavable, IContextMenu
15+
public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu
1616
{
1717
private PluginInitContext context;
1818

1919
private List<Bookmark> cachedBookmarks = new List<Bookmark>();
2020

2121
private Settings _settings { get; set;}
22-
private PluginJsonStorage<Settings> _storage { get; set;}
2322

2423
public void Init(PluginInitContext context)
2524
{
2625
this.context = context;
2726

28-
_storage = new PluginJsonStorage<Settings>();
29-
_settings = _storage.Load();
27+
_settings = context.API.LoadSettingJsonStorage<Settings>();
3028

3129
cachedBookmarks = Bookmarks.LoadAllBookmarks();
3230
}
@@ -113,11 +111,6 @@ public Control CreateSettingPanel()
113111
return new SettingsControl(_settings);
114112
}
115113

116-
public void Save()
117-
{
118-
_storage.Save();
119-
}
120-
121114
public List<Result> LoadContextMenus(Result selectedResult)
122115
{
123116
return new List<Result>() {

Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"Name": "Browser Bookmarks",
55
"Description": "Search your browser bookmarks",
66
"Author": "qianlifeng, Ioannis G.",
7-
"Version": "1.4.3",
7+
"Version": "1.4.4",
88
"Language": "csharp",
99
"Website": "https://github.com/Flow-Launcher/Flow.Launcher",
1010
"ExecuteFileName": "Flow.Launcher.Plugin.BrowserBookmark.dll",

Plugins/Flow.Launcher.Plugin.Calculator/Main.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace Flow.Launcher.Plugin.Caculator
1414
{
15-
public class Main : IPlugin, IPluginI18n, ISavable, ISettingProvider
15+
public class Main : IPlugin, IPluginI18n, ISettingProvider
1616
{
1717
private static readonly Regex RegValidExpressChar = new Regex(
1818
@"^(" +
@@ -30,17 +30,11 @@ public class Main : IPlugin, IPluginI18n, ISavable, ISettingProvider
3030
private static Settings _settings;
3131
private static SettingsViewModel _viewModel;
3232

33-
static Main()
34-
{
35-
36-
}
37-
3833
public void Init(PluginInitContext context)
3934
{
4035
Context = context;
41-
42-
_viewModel = new SettingsViewModel();
43-
_settings = _viewModel.Settings;
36+
_settings = context.API.LoadSettingJsonStorage<Settings>();
37+
_viewModel = new SettingsViewModel(_settings);
4438

4539
MagesEngine = new Engine(new Configuration
4640
{
@@ -187,10 +181,5 @@ public Control CreateSettingPanel()
187181
{
188182
return new CalculatorSettings(_viewModel);
189183
}
190-
191-
public void Save()
192-
{
193-
_viewModel.Save();
194-
}
195184
}
196185
}

0 commit comments

Comments
 (0)