11using System . Collections . Concurrent ;
22using System . Collections . Generic ;
3+ using System . Text . Json ;
34using System . Threading . Tasks ;
45using System . Windows ;
56using System . Windows . Controls ;
@@ -18,11 +19,11 @@ public class JsonRPCPluginSettings
1819 public required string SettingPath { get ; init ; }
1920 public Dictionary < string , FrameworkElement > SettingControls { get ; } = new ( ) ;
2021
21- public IReadOnlyDictionary < string , object > Inner => Settings ;
22- protected ConcurrentDictionary < string , object > Settings { get ; set ; } = null ! ;
22+ public IReadOnlyDictionary < string , object ? > Inner => Settings ;
23+ protected ConcurrentDictionary < string , object ? > Settings { get ; set ; } = null ! ;
2324 public required IPublicAPI API { get ; init ; }
2425
25- private JsonStorage < ConcurrentDictionary < string , object > > _storage = null ! ;
26+ private JsonStorage < ConcurrentDictionary < string , object ? > > _storage = null ! ;
2627
2728 private static readonly Thickness SettingPanelMargin = ( Thickness ) Application . Current . FindResource ( "SettingPanelMargin" ) ;
2829 private static readonly Thickness SettingPanelItemLeftMargin = ( Thickness ) Application . Current . FindResource ( "SettingPanelItemLeftMargin" ) ;
@@ -31,25 +32,56 @@ public class JsonRPCPluginSettings
3132
3233 public async Task InitializeAsync ( )
3334 {
34- _storage = new JsonStorage < ConcurrentDictionary < string , object > > ( SettingPath ) ;
35- Settings = await _storage . LoadAsync ( ) ;
35+ if ( Settings == null )
36+ {
37+ _storage = new JsonStorage < ConcurrentDictionary < string , object ? > > ( SettingPath ) ;
38+ Settings = await _storage . LoadAsync ( ) ;
39+
40+ // Because value type of settings dictionary is object which causes them to be JsonElement when loading from json files,
41+ // we need to convert it to the correct type
42+ foreach ( var ( key , value ) in Settings )
43+ {
44+ if ( value is JsonElement jsonElement )
45+ {
46+ Settings [ key ] = jsonElement . ValueKind switch
47+ {
48+ JsonValueKind . String => jsonElement . GetString ( ) ?? value ,
49+ JsonValueKind . True => jsonElement . GetBoolean ( ) ,
50+ JsonValueKind . False => jsonElement . GetBoolean ( ) ,
51+ JsonValueKind . Null => null ,
52+ _ => value
53+ } ;
54+ }
55+ }
56+ }
3657
3758 if ( Configuration == null )
3859 {
3960 return ;
4061 }
4162
42- foreach ( var ( _ , attributes ) in Configuration . Body )
63+ foreach ( var ( type , attributes ) in Configuration . Body )
4364 {
4465 // Skip if the setting does not have attributes or name
4566 if ( attributes ? . Name == null )
4667 {
4768 continue ;
4869 }
4970
50- if ( ! Settings . ContainsKey ( attributes . Name ) )
71+ if ( NeedSaveInSettings ( type ) )
5172 {
52- Settings [ attributes . Name ] = attributes . DefaultValue ;
73+ // If need save in settings, we need to make sure the setting exists in the settings file
74+ if ( ! Settings . ContainsKey ( attributes . Name ) )
75+ {
76+ if ( type == "checkbox" )
77+ {
78+ Settings [ attributes . Name ] = bool . Parse ( attributes . DefaultValue ) ;
79+ }
80+ else
81+ {
82+ Settings [ attributes . Name ] = attributes . DefaultValue ;
83+ }
84+ }
5385 }
5486 }
5587 }
@@ -103,8 +135,8 @@ public void Save()
103135
104136 public Control ? CreateSettingPanel ( )
105137 {
106- // If there are no settings or the settings are empty, return null
107- if ( Configuration == null || Settings == null || Settings . IsEmpty )
138+ // If there are no settings or the settings configuration is empty, return null
139+ if ( Configuration == null || Settings == null || Configuration . Body . Count == 0 )
108140 {
109141 return null ;
110142 }
@@ -291,7 +323,7 @@ public void Save()
291323 {
292324 var textBox = new TextBox ( )
293325 {
294- Height = 150 ,
326+ MaxHeight = 150 ,
295327 MinWidth = 180 ,
296328 HorizontalAlignment = HorizontalAlignment . Left ,
297329 VerticalAlignment = VerticalAlignment . Center ,
@@ -449,8 +481,8 @@ Settings[attributes.Name] is bool isChecked
449481 Grid . SetRow ( contentControl , rowCount ) ;
450482 }
451483
452- // Add into SettingControls for later use if need
453- if ( type != "textBlock" && type != "seperator" )
484+ // Add into SettingControls for settings storage if need
485+ if ( NeedSaveInSettings ( type ) )
454486 {
455487 SettingControls [ attributes . Name ] = contentControl ;
456488 }
@@ -464,5 +496,10 @@ Settings[attributes.Name] is bool isChecked
464496 Content = mainPanel
465497 } ;
466498 }
499+
500+ private static bool NeedSaveInSettings ( string type )
501+ {
502+ return type != "textBlock" && type != "seperator" && type != "hyperlink" ;
503+ }
467504 }
468505}
0 commit comments