Skip to content

Commit 2e0144a

Browse files
committed
🎨 settings provider now loading w/ edits
1 parent 2b0ca78 commit 2e0144a

10 files changed

+184
-15
lines changed

Biyori/App.xaml.cs

+6
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@ namespace Biyori
1313
/// </summary>
1414
public partial class App : Application
1515
{
16+
public readonly static ServiceProvider ServiceProvider = new ServiceProvider();
17+
protected override void OnStartup(StartupEventArgs e)
18+
{
19+
base.OnStartup(e);
20+
ServiceProvider.ScanCurrent();
21+
}
1622
}
1723
}

Biyori/Biyori.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
<Compile Include="Lib\Controls\CardControl.cs" />
203203
<Compile Include="Lib\WPF\MarginSetter.cs" />
204204
<Compile Include="Lib\WPF\Spacing.cs" />
205+
<Compile Include="ServiceProvider.cs" />
205206
<Compile Include="Settings\Frames\SettingsPage-Accounts.xaml.cs">
206207
<DependentUpon>SettingsPage-Accounts.xaml</DependentUpon>
207208
</Compile>

Biyori/FodyWeavers.xml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
22
<Costura CreateTemporaryAssemblies="true" DisableCleanup="true" DisableCompression="true" />
3+
<PropertyChanged/>
34
</Weavers>

Biyori/MainWindow.xaml.cs

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ public MainWindow()
3030
protected override void OnInitialized(EventArgs e)
3131
{
3232
base.OnInitialized(e);
33-
new Settings.SettingsProvider();
3433
}
3534

3635
private void onSettingsClick(object sender, RoutedEventArgs e)

Biyori/ServiceProvider.cs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Biyori
9+
{
10+
public class ServiceProvider
11+
{
12+
private List<ServiceProviderBase> serviceProviders { get; set; }
13+
public ServiceProvider()
14+
{
15+
this.serviceProviders = new List<ServiceProviderBase>();
16+
}
17+
18+
public T GetProvider<T>() where T : ServiceProviderBase
19+
{
20+
return GetProvider(typeof(T)) as T;
21+
}
22+
23+
private object GetProvider(Type type)
24+
{
25+
return serviceProviders.Where(x => x.GetType() == type).FirstOrDefault();
26+
}
27+
public void Add<T>(T serviceProvider) where T : ServiceProviderBase
28+
{
29+
this.serviceProviders.Add(serviceProvider);
30+
}
31+
public void Remove<T>(T serviceProvider) where T : ServiceProviderBase
32+
{
33+
this.serviceProviders.RemoveAll(x => x.GetType() == serviceProvider.GetType());
34+
}
35+
public void AddOrUpdateRange<T>(IEnumerable<T> serviceProviders) where T : ServiceProviderBase
36+
{
37+
foreach(var sp in serviceProviders)
38+
{
39+
this.AddOrUpdate(sp);
40+
}
41+
}
42+
public void AddOrUpdate<T>(T serviceProvider) where T : ServiceProviderBase
43+
{
44+
if (this.serviceProviders.Where(x => x.GetType() == serviceProvider.GetType()).Count() == 0)
45+
{
46+
this.serviceProviders.Add(serviceProvider);
47+
} else
48+
{
49+
this.serviceProviders.Remove(serviceProvider);
50+
this.AddOrUpdate(serviceProvider);
51+
}
52+
}
53+
public void ScanCurrent() => ScanAssembly(Assembly.GetEntryAssembly());
54+
public void ScanAssembly(Assembly assembly)
55+
{
56+
var providers = assembly.GetTypes().Where(x => x.GetCustomAttributes<ServiceProviderParseAttribute>().Count() > 0);
57+
var provderInstances = providers.Select(x =>
58+
{
59+
var attr = x.GetCustomAttribute<ServiceProviderParseAttribute>();
60+
var instance = Activator.CreateInstance(x);
61+
if (attr.InitializeOnStartup)
62+
{
63+
instance.GetType().GetMethod("OnInitialize")?.Invoke(instance, new object[] { });
64+
}
65+
return instance as ServiceProviderBase;
66+
});
67+
this.AddOrUpdateRange(provderInstances);
68+
}
69+
}
70+
public abstract class ServiceProviderBase
71+
{
72+
private void OnInitialize()
73+
{
74+
}
75+
}
76+
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
77+
public class ServiceProviderParseAttribute : Attribute
78+
{
79+
public ServiceProviderParseAttribute(string name)
80+
{
81+
Name = name;
82+
}
83+
84+
public string Name { get; set; }
85+
public bool InitializeOnStartup { get; set; } = false;
86+
}
87+
}

Biyori/Settings/Frames/SettingsPage-Accounts.xaml

+22-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,30 @@
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:local="clr-namespace:Biyori.Settings.Frames"
7-
mc:Ignorable="d"
7+
mc:Ignorable="d"
8+
x:Name="root"
89
d:DesignHeight="450" d:DesignWidth="800"
910
Title="SettingsPage_Accounts">
1011

11-
<Grid>
12-
<TextBlock>Accounts Page Works!</TextBlock>
12+
<Grid Margin="10" DataContext="{Binding ElementName=root}">
13+
<TabControl>
14+
<TabItem Header="General" IsSelected="True">
15+
<ListBox ItemsSource="{Binding Path=accountInfo}">
16+
<ListBox.ItemTemplate>
17+
<DataTemplate>
18+
<StackPanel Orientation="Vertical">
19+
<TextBlock>
20+
<Run Text="("/>
21+
<Run Text="{Binding Path=TypeString, Mode=OneWay}" FontWeight="Bold" />
22+
<Run Text=")"/>
23+
<TextBlock Margin="4,0,0,0" Text="{Binding Path=Username}" FontWeight="Bold" />
24+
</TextBlock>
25+
<TextBlock Text="{Binding Path=EmailAddress}" />
26+
</StackPanel>
27+
</DataTemplate>
28+
</ListBox.ItemTemplate>
29+
</ListBox>
30+
</TabItem>
31+
</TabControl>
1332
</Grid>
1433
</Page>

Biyori/Settings/Frames/SettingsPage-Accounts.xaml.cs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Converters;
3+
using PropertyChanged;
24
using System;
35
using System.Collections.Generic;
6+
using System.ComponentModel;
47
using System.Linq;
58
using System.Text;
69
using System.Threading.Tasks;
@@ -16,26 +19,30 @@
1619

1720
namespace Biyori.Settings.Frames
1821
{
19-
[SettingsRoute("accounts", "Accounts", false)]
22+
[AddINotifyPropertyChangedInterface]
23+
[SettingsRoute("accounts", "Accounts")]
2024
/// <summary>
2125
/// Interaction logic for SettingsPage_Accounts.xaml
2226
/// </summary>
2327
public partial class SettingsPage_Accounts : Page
2428
{
29+
private SettingsProvider settingsProvider { get => App.ServiceProvider.GetProvider<SettingsProvider>(); }
30+
private List<AccountInfo> _accountInfo { get => this.settingsProvider.GetConfig<AccountSettings>()?.Accounts; }
31+
public List<AccountInfo> accountInfo { get; set; } = new List<AccountInfo>();
2532
public SettingsPage_Accounts()
2633
{
2734
InitializeComponent();
35+
this.accountInfo.Clear();
36+
this.accountInfo = _accountInfo;
2837
}
2938
}
3039
[SettingsSection("account", true)]
31-
public class AccountSettings
40+
public class AccountSettings : SettingsBase
3241
{
3342
[JsonProperty("enable_sync")]
34-
public bool SyncEnabled { get; set; }
43+
public bool SyncEnabled { get; set; } = false;
3544
[JsonProperty("accounts")]
36-
public List<AccountInfo> Accounts { get; set; }
37-
[JsonProperty("current_account_type")]
38-
public AccountEndpoints CurrentAccountType { get; set; }
45+
public List<AccountInfo> Accounts { get; set; } = new List<AccountInfo>();
3946
[JsonProperty("current_account")]
4047
public AccountInfo CurrentAccount { get; set; }
4148
}
@@ -47,6 +54,10 @@ public class AccountInfo
4754
public string Username { get; set; }
4855
[JsonProperty("password")]
4956
public string Password { get; set; }
57+
[JsonProperty("account_type"), JsonConverter(typeof(StringEnumConverter))]
58+
public AccountEndpoints Type { get; set; } = AccountEndpoints.Kitsu;
59+
[JsonIgnore]
60+
public string TypeString { get => this.Type.ToString(); }
5061
}
5162
public enum AccountEndpoints
5263
{

Biyori/Settings/SettingsProvider.cs

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Newtonsoft.Json;
2+
using PropertyChanged;
23
using System;
34
using System.Collections.Generic;
45
using System.IO;
@@ -9,17 +10,29 @@
910

1011
namespace Biyori.Settings
1112
{
12-
public class SettingsProvider
13+
[AddINotifyPropertyChangedInterface]
14+
[ServiceProviderParse("settings", InitializeOnStartup = true)]
15+
public class SettingsProvider : ServiceProviderBase
1316
{
1417
private string configPath { get => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config"); }
1518
private string settingsPath { get => Path.Combine(configPath, "settings.json"); }
19+
private List<SettingsBase> Settings { get; set; } = new List<SettingsBase>();
20+
1621
public SettingsProvider()
1722
{
1823
if (!Directory.Exists(this.configPath))
1924
{
2025
Directory.CreateDirectory(this.configPath);
26+
}
27+
if (!File.Exists(this.settingsPath))
28+
{
2129
initializeConfig();
2230
}
31+
this.Settings.AddRange(
32+
Assembly.GetEntryAssembly().GetTypes()
33+
.Where(x => x.GetCustomAttributes<SettingsSectionAttribute>().Count() > 0)
34+
.Select(x => Activator.CreateInstance(x) as SettingsBase));
35+
2336
}
2437
private void initializeConfig()
2538
{
@@ -35,7 +48,17 @@ private void initializeConfig()
3548
});
3649
File.WriteAllText(this.settingsPath, JsonConvert.SerializeObject(sections, Formatting.Indented));
3750
}
51+
public T GetConfig<T>() where T : SettingsBase
52+
{
53+
return this.Settings.FirstOrDefault(x => x.GetType() == typeof(T)) as T;
54+
}
55+
public void UpdateConfig<T>(T settings) where T : SettingsBase
56+
{
57+
var itemIndex = this.Settings.FindIndex(x => x.GetType() == typeof(T));
58+
this.Settings[itemIndex] = settings;
59+
}
3860
}
61+
public abstract class SettingsBase { }
3962
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
4063
public class SettingsSectionAttribute : Attribute
4164
{

Biyori/Settings/SettingsWindow.xaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
</Grid>
4949
<Grid Grid.Column="1" Grid.Row="2">
5050
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" wpf:MarginSetter.Margin="8, 0" Margin="8, 0">
51-
<Button Style="{StaticResource NavButtons}" HorizontalAlignment="Right" VerticalAlignment="Center" Content="Save Changes"></Button>
51+
<Button Style="{StaticResource NavButtons}" Click="SaveChange_Click" HorizontalAlignment="Right" VerticalAlignment="Center" Content="Save Changes"></Button>
5252
</StackPanel>
5353
</Grid>
5454
</Grid>

Biyori/Settings/SettingsWindow.xaml.cs

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using System;
1+
using Biyori.Settings.Frames;
2+
using Newtonsoft.Json;
3+
using System;
24
using System.Collections.Generic;
5+
using System.Diagnostics;
36
using System.Linq;
47
using System.Reflection;
58
using System.Text;
@@ -33,11 +36,25 @@ public SettingsWindow()
3336
IsEnabled = x.isEnabled
3437
}).ToList().ForEach(x => settingsNav.Items.Add(x));
3538
}
39+
protected override void OnInitialized(EventArgs e)
40+
{
41+
base.OnInitialized(e);
42+
var sp = App.ServiceProvider.GetProvider<SettingsProvider>();
43+
var accountConfig = sp.GetConfig<AccountSettings>();
44+
accountConfig.Accounts.Add(new AccountInfo()
45+
{
46+
Username = "test",
47+
Password = "testPassword",
48+
EmailAddress = "[email protected]"
49+
});
50+
sp.UpdateConfig(accountConfig);
51+
Debug.WriteLine(JsonConvert.SerializeObject(sp.GetConfig<AccountSettings>()));
52+
}
3653

3754
private void SettingsNav_SelectionChanged(object sender, SelectionChangedEventArgs e)
3855
{
3956
var item = e.AddedItems[0] as ListBoxItem;
40-
if (item != null & item.Tag != null && this.TryGetRoute(item.Tag?.ToString()?.ToLower(), out var page))
57+
if (item != null && item.IsEnabled && item.Tag != null && this.TryGetRoute(item.Tag?.ToString()?.ToLower(), out var page))
4158
{
4259
settingsFrame.Navigate(new Uri(page.RelativeRoute));
4360
}
@@ -67,12 +84,17 @@ private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
6784
this.Close();
6885
}
6986
}
87+
88+
private void SaveChange_Click(object sender, RoutedEventArgs e)
89+
{
90+
this.Close();
91+
}
7092
}
7193

7294
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
7395
public class SettingsRouteAttribute : Attribute
7496
{
75-
public SettingsRouteAttribute(string key, string pageName, bool isEnabled)
97+
public SettingsRouteAttribute(string key, string pageName, bool isEnabled = true)
7698
{
7799
this.key = key;
78100
this.pageName = pageName;

0 commit comments

Comments
 (0)