Skip to content

Commit 4513a62

Browse files
author
Meyn
committed
Refactored app architecture
1 parent 1b3e159 commit 4513a62

File tree

180 files changed

+4222
-1445
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+4222
-1445
lines changed

Elva/App.xaml

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,85 +2,87 @@
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:local="clr-namespace:Elva"
5-
xmlns:conv="clr-namespace:Elva.Core.Converter"
6-
xmlns:view="clr-namespace:Elva.MVVM.View.CControl"
7-
xmlns:vm="clr-namespace:Elva.MVVM.ViewModel.CControl"
8-
xmlns:vm1="clr-namespace:Elva.MVVM.ViewModel.CControl.Home"
9-
xmlns:view1="clr-namespace:Elva.MVVM.View.CControl.Home"
10-
xmlns:vm2="clr-namespace:Elva.MVVM.ViewModel.CControl.Search"
11-
xmlns:view2="clr-namespace:Elva.MVVM.View.CControl.Search"
12-
xmlns:vm3="clr-namespace:Elva.MVVM.ViewModel.CControl.Info"
13-
xmlns:view3="clr-namespace:Elva.MVVM.View.CControl.Info"
14-
xmlns:vm4="clr-namespace:Elva.MVVM.ViewModel.CControl.WebsiteMenu"
15-
xmlns:view4="clr-namespace:Elva.MVVM.View.CControl.WebsiteMenu"
16-
xmlns:vm5="clr-namespace:Elva.MVVM.ViewModel.CControl.Settings"
17-
xmlns:view5="clr-namespace:Elva.MVVM.View.CControl.Settings"
5+
xmlns:conv="clr-namespace:Elva.Common.Converters"
6+
xmlns:homeView="clr-namespace:Elva.Pages.Home.Views"
7+
xmlns:homeVm="clr-namespace:Elva.Pages.Home.ViewModels"
8+
xmlns:searchView="clr-namespace:Elva.Pages.Search.Views"
9+
xmlns:searchVm="clr-namespace:Elva.Pages.Search.ViewModels"
10+
xmlns:infoView="clr-namespace:Elva.Pages.Info.Views"
11+
xmlns:infoVm="clr-namespace:Elva.Pages.Info.ViewModels"
12+
xmlns:websiteView="clr-namespace:Elva.Pages.WebsiteMenu.Views"
13+
xmlns:websiteVm="clr-namespace:Elva.Pages.WebsiteMenu.ViewModels"
14+
xmlns:settingsView="clr-namespace:Elva.Pages.Settings.Views"
15+
xmlns:settingsVm="clr-namespace:Elva.Pages.Settings.ViewModels"
1816
xmlns:sys="clr-namespace:System;assembly=netstandard">
1917
<Application.Resources>
2018
<ResourceDictionary>
2119
<ResourceDictionary.MergedDictionaries>
2220
<!-- Theme dictionaries -->
23-
<ResourceDictionary Source="/Style/ThemeDark.xaml"
21+
<ResourceDictionary Source="/Resources/Styles/ThemeDark.xaml"
2422
x:Name="ThemeDictionary" />
2523

2624
<!-- Animation dictionary -->
27-
<ResourceDictionary Source="/Style/Animations.xaml" />
28-
29-
<!-- Animated Cards -->
30-
<ResourceDictionary Source="/Style/AnimatedCard.xaml" />
25+
<ResourceDictionary Source="/Resources/Styles/Animations.xaml" />
26+
<ResourceDictionary Source="/Resources/Styles/AnimatedCard.xaml" />
3127

3228
<!-- Existing style dictionaries -->
33-
<ResourceDictionary Source="/Style/ModernWindow.xaml" />
34-
<ResourceDictionary Source="/Style/WindowMenuButton.xaml" />
35-
<ResourceDictionary Source="/Style/ModernScrollBar.xaml" />
36-
<ResourceDictionary Source="/Style/ModernButton.xaml" />
37-
<ResourceDictionary Source="/Style/ModernSearchBar.xaml" />
38-
<ResourceDictionary Source="/Style/ModernTextBox.xaml" />
39-
<ResourceDictionary Source="/Style/ModernComboBox.xaml" />
40-
<ResourceDictionary Source="/Style/FilterButton.xaml" />
41-
<ResourceDictionary Source="/Style/TextBlockTextBox.xaml" />
42-
<ResourceDictionary Source="/Style/ModernRadioButton.xaml" />
29+
<ResourceDictionary Source="/Resources/Styles/ModernWindow.xaml" />
30+
<ResourceDictionary Source="/Resources/Styles/WindowMenuButton.xaml" />
31+
<ResourceDictionary Source="/Resources/Styles/ModernScrollBar.xaml" />
32+
<ResourceDictionary Source="/Resources/Styles/ModernButton.xaml" />
33+
<ResourceDictionary Source="/Resources/Styles/ModernSearchBar.xaml" />
34+
<ResourceDictionary Source="/Resources/Styles/ModernTextBox.xaml" />
35+
<ResourceDictionary Source="/Resources/Styles/ModernComboBox.xaml" />
36+
<ResourceDictionary Source="/Resources/Styles/FilterButton.xaml" />
37+
<ResourceDictionary Source="/Resources/Styles/TextBlockTextBox.xaml" />
38+
<ResourceDictionary Source="/Resources/Styles/ModernRadioButton.xaml" />
4339
</ResourceDictionary.MergedDictionaries>
4440

45-
<sys:String x:Key="NullImagePath">pack://application:,,,/Recource/Image/Comic/no_image.jpg</sys:String>
41+
<sys:String x:Key="NullImagePath">pack://application:,,,/Resources/Images/Comic/no_image.jpg</sys:String>
4642
<conv:DictionaryBoolConverter x:Key="DictionaryConverter" />
4743
<conv:MultiValueEqualityConverter x:Key="MultiEqualtityConverter" />
4844
<conv:ProgressRangeConverter x:Key="ProgressRangeConverter" />
4945
<conv:MultiBindingConverter x:Key="MultiBindingConverter" />
5046
<conv:BooleanToColorBrushConverter x:Key="BooleanToColorBrushConverter" />
5147
<conv:ImageConverter x:Key="ImageConverter" />
5248

53-
<DataTemplate DataType="{x:Type vm1:HomeVM}">
54-
<view1:HomeView />
49+
<DataTemplate DataType="{x:Type homeVm:HomeVM}">
50+
<homeView:HomeView />
5551
</DataTemplate>
56-
<DataTemplate DataType="{x:Type vm2:SearchVM}">
57-
<view2:SearchView />
52+
<DataTemplate DataType="{x:Type homeVm:HomeWebsiteVM}">
53+
<homeView:HomeWebsiteView />
5854
</DataTemplate>
59-
<DataTemplate DataType="{x:Type vm3:InfoVM}">
60-
<view3:InfoView />
55+
<DataTemplate DataType="{x:Type searchVm:SearchVM}">
56+
<searchView:SearchView />
6157
</DataTemplate>
62-
<DataTemplate DataType="{x:Type vm4:WebsiteMenuVM}">
63-
<view4:WebsiteMenuView />
58+
<DataTemplate DataType="{x:Type searchVm:SourceVM}">
59+
<searchView:SourceView />
6460
</DataTemplate>
65-
<DataTemplate DataType="{x:Type vm5:SettingsVM}">
66-
<view5:SettingsView />
61+
<DataTemplate DataType="{x:Type searchVm:GenreVM}">
62+
<searchView:GenreView />
6763
</DataTemplate>
68-
<DataTemplate DataType="{x:Type vm5:LicenseInfoVM}">
69-
<view5:LicenseInfoView />
64+
<DataTemplate DataType="{x:Type searchVm:InputVM}">
65+
<searchView:InputView />
7066
</DataTemplate>
71-
72-
<DataTemplate DataType="{x:Type vm2:SourceVM}">
73-
<view2:SourceView />
67+
<DataTemplate DataType="{x:Type searchVm:OtherVM}">
68+
<searchView:OtherView />
69+
</DataTemplate>
70+
<DataTemplate DataType="{x:Type infoVm:InfoVM}">
71+
<infoView:InfoView />
7472
</DataTemplate>
75-
<DataTemplate DataType="{x:Type vm2:GenreVM}">
76-
<view2:GenreView />
73+
<DataTemplate DataType="{x:Type infoVm:ChapterInfoVM}">
74+
<infoView:ChapterInfoView />
7775
</DataTemplate>
78-
<DataTemplate DataType="{x:Type vm2:InputVM}">
79-
<view2:InputView />
76+
<DataTemplate DataType="{x:Type websiteVm:WebsiteMenuVM}">
77+
<websiteView:WebsiteMenuView />
8078
</DataTemplate>
81-
<DataTemplate DataType="{x:Type vm2:OtherVM}">
82-
<view2:OtherView />
79+
<DataTemplate DataType="{x:Type settingsVm:SettingsVM}">
80+
<settingsView:SettingsView />
8381
</DataTemplate>
82+
<DataTemplate DataType="{x:Type settingsVm:LicenseInfoVM}">
83+
<settingsView:LicenseInfoView />
84+
</DataTemplate>
85+
8486
<BooleanToVisibilityConverter x:Key="BoolToVis" />
8587
</ResourceDictionary>
8688
</Application.Resources>

Elva/App.xaml.cs

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
using Elva.Core;
2-
using Elva.MVVM.Model;
3-
using Elva.MVVM.Model.Database;
4-
using Elva.MVVM.Model.Manager;
5-
using Elva.MVVM.ViewModel.CControl.Home;
6-
using Elva.MVVM.ViewModel.CControl.Info;
7-
using Elva.MVVM.ViewModel.CControl.Search;
8-
using Elva.MVVM.ViewModel.CControl.Settings;
9-
using Elva.MVVM.ViewModel.CControl.WebsiteMenu;
10-
using Elva.MVVM.ViewModel.Window;
1+
using Elva.Common;
2+
using Elva.Common.Navigation;
3+
using Elva.Pages.Home.ViewModels;
4+
using Elva.Pages.Info.ViewModels;
5+
using Elva.Pages.Search.ViewModels;
6+
using Elva.Pages.Settings.ViewModels;
7+
using Elva.Pages.Shared.Models;
8+
using Elva.Pages.WebsiteMenu.ViewModels;
9+
using Elva.Pages.Windows.View;
10+
using Elva.Pages.Windows.ViewModel;
11+
using Elva.Services.Database;
1112
using Microsoft.Extensions.DependencyInjection;
1213
using Microsoft.Extensions.Hosting;
1314
using Microsoft.Extensions.Logging;
@@ -36,7 +37,7 @@ public App(ILoggerFactory loggerF)
3637
IServiceCollection services = new ServiceCollection();
3738
services.AddLogging(options => options.AddSimpleConsole(c => { c.TimestampFormat = "[yyyy-MM-dd HH:mm:ss] "; c.UseUtcTimestamp = true; }).AddDebug());
3839
services.AddSingleton(provider => new MainWindow { DataContext = provider.GetRequiredService<MainWindowVM>() });
39-
services.AddSingleton(provider => new WebsiteManager(IOManager.LoadWebsites()));
40+
services.AddSingleton(_ => new WebsiteManager(IOManager.LoadWebsites()));
4041
services.AddSingleton<ComicDatabaseManager>();
4142
services.AddSingleton<SettingsManager>();
4243
services.AddSingleton<SearchManager>();
@@ -110,35 +111,23 @@ protected override void OnExit(ExitEventArgs e)
110111
/// </summary>
111112
public void ApplyTheme(string theme)
112113
{
113-
ResourceDictionary themeDictionary = null;
114-
115-
// Determine which theme to use
116114
if (theme == "System")
117115
{
118-
// Check if system is using dark mode
119116
bool systemUsesDarkTheme = IsSystemUseDarkTheme();
120117
theme = systemUsesDarkTheme ? "Dark" : "Light";
121118
}
122119

123-
// Load the appropriate theme dictionary
124-
string packUri = $"pack://application:,,,/Style/Theme{theme}.xaml";
125-
themeDictionary = new ResourceDictionary() { Source = new Uri(packUri, UriKind.Absolute) };
126-
127-
// Remove any existing theme dictionaries
120+
string packUri = $"pack://application:,,,/Resources/Styles/Theme{theme}.xaml";
121+
ResourceDictionary themeDictionary = new() { Source = new Uri(packUri, UriKind.Absolute) };
128122
for (int i = Resources.MergedDictionaries.Count - 1; i >= 0; i--)
129123
{
130124
ResourceDictionary dict = Resources.MergedDictionaries[i];
131-
if (dict.Source != null && dict.Source.OriginalString.Contains("Theme"))
132-
{
125+
if (dict.Source?.OriginalString.Contains("Theme") == true)
133126
Resources.MergedDictionaries.RemoveAt(i);
134-
}
135127
}
136128

137-
// Add the new theme dictionary
138129
if (themeDictionary != null)
139-
{
140130
Resources.MergedDictionaries.Insert(0, themeDictionary);
141-
}
142131
}
143132

144133
/// <summary>
@@ -148,25 +137,17 @@ private bool IsSystemUseDarkTheme()
148137
{
149138
try
150139
{
151-
// Check Windows registry for dark mode setting
152-
using Microsoft.Win32.RegistryKey? key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(
153-
@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
140+
using Microsoft.Win32.RegistryKey? key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
154141

155142
if (key != null)
156143
{
157-
object value = key.GetValue("AppsUseLightTheme");
144+
object? value = key.GetValue("AppsUseLightTheme");
158145
if (value != null && value is int lightThemeEnabled)
159-
{
160-
return lightThemeEnabled == 0; // 0 means dark theme is enabled
161-
}
146+
return lightThemeEnabled == 0;
162147
}
163148
}
164-
catch
165-
{
166-
// If we can't read the registry, default to dark theme
167-
}
168-
169-
return true; // Default to dark theme if we can't determine
149+
catch { }
150+
return true;
170151
}
171152
public static void Log(string information, LogLevel logLevel = LogLevel.Information) => Current._logger.Log(logLevel, information);
172153
public static void Log<T>(string information, LogLevel logLevel = LogLevel.Information, bool time = false, [CallerMemberName] string callerName = "", [CallerLineNumber] long callerLineNumber = 0) =>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System.Windows;
22

3-
namespace Elva.Core
3+
namespace Elva.Common
44
{
55
public class BindingProxy : Freezable
66
{

Elva/MVVM/View/CElement/LoadingPlaceholder.xaml renamed to Elva/Common/Controls/LoadingPlaceholder.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<UserControl x:Class="Elva.MVVM.View.CElement.LoadingPlaceholder"
1+
<UserControl x:Class="Elva.Common.Controls.LoadingPlaceholder"
22
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

Elva/MVVM/View/CElement/LoadingPlaceholder.xaml.cs renamed to Elva/Common/Controls/LoadingPlaceholder.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System.Windows.Controls;
22

3-
namespace Elva.MVVM.View.CElement
3+
namespace Elva.Common.Controls
44
{
55
public partial class LoadingPlaceholder : UserControl
66
{

Elva/MVVM/View/CElement/LottieAnimationView.cs renamed to Elva/Common/Controls/LottieAnimationView.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
using System.IO;
1111
using System.Windows;
1212

13-
namespace Elva.MVVM.View.CElement
13+
namespace Elva.Common.Controls
1414
{
1515
public class LottieAnimationView : SKElement
1616
{
@@ -132,6 +132,19 @@ private void SetAnimationFromResource(string assetUri)
132132

133133
}
134134

135+
public void Reload()
136+
{
137+
if (!string.IsNullOrEmpty(ResourcePath))
138+
{
139+
double currentTime = AnimationTime;
140+
animation?.Dispose();
141+
animation = null;
142+
SetAnimationFromResource(ResourcePath);
143+
AnimationTime = currentTime;
144+
InvalidateVisual();
145+
}
146+
}
147+
135148
private void SetAnimation(Stream stream)
136149
{
137150
using SKManagedStream fileStream = new(stream);

0 commit comments

Comments
 (0)