Skip to content

Commit 77c290c

Browse files
author
Meyn
committed
Improve startup speed
1 parent 4513a62 commit 77c290c

File tree

17 files changed

+801
-299
lines changed

17 files changed

+801
-299
lines changed

Elva/App.xaml.cs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Runtime.CompilerServices;
1818
using System.Threading.Tasks;
1919
using System.Windows;
20+
using System.Windows.Threading;
2021

2122
namespace Elva
2223
{
@@ -31,6 +32,9 @@ public partial class App : Application
3132

3233
private readonly ILogger<App> _logger;
3334

35+
public event EventHandler<string>? OnThemeChanged;
36+
private MainWindow? _mainWindow;
37+
3438
public App(ILoggerFactory loggerF)
3539
{
3640
_logger = loggerF.CreateLogger<App>();
@@ -67,35 +71,45 @@ protected override void OnStartup(StartupEventArgs e)
6771
{
6872
Log<App>("Start Application", time: true);
6973
base.OnStartup(e);
70-
Task database = _serviceProvider.GetRequiredService<ComicDatabaseManager>().LoadDataAsync();
74+
_ = _serviceProvider.GetRequiredService<ComicDatabaseManager>().LoadDataAsync();
75+
7176
SettingsManager settingsManager = _serviceProvider.GetRequiredService<SettingsManager>();
7277
settingsManager.LoadSettings();
73-
74-
// Apply the saved theme
78+
SetupConnectionManager(settingsManager);
79+
_serviceProvider.GetRequiredService<INavigationService>().NavigateTo<HomeVM>();
80+
_mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
81+
_mainWindow.Show();
7582
ApplyTheme(settingsManager.Theme);
7683

84+
Log<App>("Show MainWindow", time: true);
85+
}
86+
87+
private void SetupConnectionManager(SettingsManager settingsManager)
88+
{
7789
ConnectionManager.ConnectionChanged += (o, s) =>
7890
{
7991
if ((!ConnectionManager.ConnectionIsSave && settingsManager.IsKillSwitchEnabled) || !ConnectionManager.ConnectionIsAvailable)
8092
{
8193
RequestHandler.CancelMainCTS();
82-
ToastNotification.Show("Downloads paused: Connection not secure", ToastType.Warning);
94+
Dispatcher.Invoke(() =>
95+
{
96+
ToastNotification.Show("Downloads paused: Connection not secure", ToastType.Warning);
97+
});
8398
}
8499
else if (ConnectionManager.ConnectionIsAvailable)
85100
{
86101
RequestHandler.CreateMainCTS();
87102
if (ConnectionManager.ConnectionIsSave)
88103
{
89-
ToastNotification.Show("Connection secure: Downloads enabled", ToastType.Success);
104+
Dispatcher.Invoke(() =>
105+
{
106+
ToastNotification.Show("Connection secure: Downloads enabled", ToastType.Success);
107+
});
90108
}
91109
}
92110
};
93-
ConnectionManager.Initialize();
94111

95-
database.Wait();
96-
_serviceProvider.GetRequiredService<INavigationService>().NavigateTo<HomeVM>();
97-
_serviceProvider.GetRequiredService<MainWindow>().Show();
98-
Log<App>("Show MainWindow", time: true);
112+
Task.Run(ConnectionManager.Initialize);
99113
}
100114

101115
protected override void OnExit(ExitEventArgs e)
@@ -119,21 +133,26 @@ public void ApplyTheme(string theme)
119133

120134
string packUri = $"pack://application:,,,/Resources/Styles/Theme{theme}.xaml";
121135
ResourceDictionary themeDictionary = new() { Source = new Uri(packUri, UriKind.Absolute) };
122-
for (int i = Resources.MergedDictionaries.Count - 1; i >= 0; i--)
136+
137+
Dispatcher.Invoke(() =>
123138
{
124-
ResourceDictionary dict = Resources.MergedDictionaries[i];
125-
if (dict.Source?.OriginalString.Contains("Theme") == true)
126-
Resources.MergedDictionaries.RemoveAt(i);
127-
}
139+
for (int i = Resources.MergedDictionaries.Count - 1; i >= 0; i--)
140+
{
141+
ResourceDictionary dict = Resources.MergedDictionaries[i];
142+
if (dict.Source?.OriginalString.Contains("Theme") == true)
143+
Resources.MergedDictionaries.RemoveAt(i);
144+
}
128145

129-
if (themeDictionary != null)
130-
Resources.MergedDictionaries.Insert(0, themeDictionary);
146+
if (themeDictionary != null)
147+
Resources.MergedDictionaries.Insert(0, themeDictionary);
148+
});
149+
OnThemeChanged?.Invoke(this, theme);
131150
}
132151

133152
/// <summary>
134153
/// Checks if the system is using dark theme
135154
/// </summary>
136-
private bool IsSystemUseDarkTheme()
155+
private static bool IsSystemUseDarkTheme()
137156
{
138157
try
139158
{
@@ -149,6 +168,7 @@ private bool IsSystemUseDarkTheme()
149168
catch { }
150169
return true;
151170
}
171+
152172
public static void Log(string information, LogLevel logLevel = LogLevel.Information) => Current._logger.Log(logLevel, information);
153173
public static void Log<T>(string information, LogLevel logLevel = LogLevel.Information, bool time = false, [CallerMemberName] string callerName = "", [CallerLineNumber] long callerLineNumber = 0) =>
154174
Current._logger.Log(logLevel, $"Time: {(time ? DateTime.Now.TimeOfDay : "")} Class: {typeof(T).FullName} Method:{callerName} Line: {callerLineNumber} »» {information} ");

Elva/Common/Converters/ThemePathConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class ThemePathConverter : IValueConverter
1313

1414
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
1515
{
16-
if (value == null) return null;
16+
if (value == null) return null!;
1717

1818
string fileName = value.ToString() ?? "";
1919
bool isDarkTheme = IsAppUsingDarkTheme();

Elva/Common/Navigation/NavigationService.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,11 @@ public interface INavigationService : INotifyPropertyChanged
1111
void NavigateTo(Type type);
1212
}
1313

14-
public partial class NavigationService : ObservableObject, INavigationService
14+
public partial class NavigationService(Func<Type, ViewModelObject> viewModelFactory) : ObservableObject, INavigationService
1515
{
1616
[ObservableProperty]
1717
private ViewModelObject _currentView = null!;
18-
private readonly Func<Type, ViewModelObject> _viewModelFactory;
19-
20-
21-
public NavigationService(Func<Type, ViewModelObject> viewModelFactory)
22-
{
23-
_viewModelFactory = viewModelFactory;
24-
}
25-
18+
private readonly Func<Type, ViewModelObject> _viewModelFactory = viewModelFactory;
2619

2720
public void NavigateTo<TViewModel>() where TViewModel : ViewModelObject
2821
{

Elva/Pages/Home/ViewModels/HomeVM.cs

Lines changed: 139 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,176 @@
33
using Elva.Common.Navigation;
44
using Elva.Pages.Shared.Models;
55
using Elva.Pages.Shared.ViewModels;
6+
using Elva.Services.Database;
67
using Microsoft.Extensions.DependencyInjection;
78
using System;
89
using System.Collections.ObjectModel;
10+
using System.Diagnostics;
911
using System.Linq;
12+
using System.Threading.Tasks;
13+
using System.Windows;
1014
using WebsiteScraper.Downloadable.Books;
1115

1216
namespace Elva.Pages.Home.ViewModels
1317
{
1418
internal partial class HomeVM : ViewModelObject
1519
{
1620
[ObservableProperty]
17-
private ObservableCollection<HomeWebsiteVM> _websites = null!;
21+
private ObservableCollection<HomeWebsiteVM> _websites = new();
22+
1823
[ObservableProperty]
19-
private ObservableCollection<ComicVM>? _favorites = null;
24+
private ObservableCollection<ComicVM>? _favorites = new();
25+
2026
[ObservableProperty]
2127
private bool _favoritesVisible = false;
22-
private WebsiteManager _websiteManagaer;
23-
private FavoriteManager _favoriteManager;
2428

25-
public ObservableCollection<ComicVM>? Favorites1 { get => _favorites; set => _favorites = value; }
29+
[ObservableProperty]
30+
private bool _isLoading = true;
31+
32+
private readonly WebsiteManager _websiteManager;
33+
private readonly FavoriteManager _favoriteManager;
34+
private readonly ComicDatabaseManager _databaseManager;
35+
private readonly SettingsManager _settingsManager;
36+
37+
public ObservableCollection<ComicVM>? Favorites1 { get => Favorites; set => Favorites = value; }
2638

2739
public HomeVM(INavigationService navigation) : base(navigation)
2840
{
29-
_websiteManagaer = App.Current.ServiceProvider.GetRequiredService<WebsiteManager>();
41+
_websiteManager = App.Current.ServiceProvider.GetRequiredService<WebsiteManager>();
3042
_favoriteManager = App.Current.ServiceProvider.GetRequiredService<FavoriteManager>();
43+
_databaseManager = App.Current.ServiceProvider.GetRequiredService<ComicDatabaseManager>();
44+
_settingsManager = App.Current.ServiceProvider.GetRequiredService<SettingsManager>();
45+
3146
_favoriteManager.FavoriteChanged += FavoriteChanged;
32-
SetFavoriteCollection();
33-
SetWebsiteCollection();
34-
_websiteManagaer.WebsiteAdded += (s, e) => SetWebsiteCollection();
47+
_websiteManager.WebsiteAdded += WebsiteManagerOnWebsiteAdded;
48+
InitializeAsync();
49+
}
50+
51+
private void WebsiteManagerOnWebsiteAdded(object? sender, EventArgs e) => Application.Current.Dispatcher.Invoke(SetWebsiteCollection);
52+
53+
private async void InitializeAsync()
54+
{
55+
try
56+
{
57+
await _settingsManager.SettingsLoadedTask;
58+
Application.Current.Dispatcher.Invoke(() =>
59+
{
60+
try
61+
{
62+
SetWebsiteCollection();
63+
}
64+
catch (Exception ex)
65+
{
66+
Debug.WriteLine($"Error setting website collection: {ex.Message}");
67+
}
68+
});
69+
await Task.Run(LoadFavorites);
70+
_databaseManager.RegisterForFullLoad(() =>
71+
{
72+
Application.Current.Dispatcher.Invoke(() =>
73+
{
74+
try
75+
{
76+
RefreshWebsiteData();
77+
IsLoading = false;
78+
}
79+
catch (Exception ex)
80+
{
81+
Debug.WriteLine($"Error refreshing website data: {ex.Message}");
82+
IsLoading = false;
83+
}
84+
});
85+
});
86+
}
87+
catch (Exception ex)
88+
{
89+
Debug.WriteLine($"Error in InitializeAsync: {ex.Message}");
90+
Application.Current.Dispatcher.Invoke(() => IsLoading = false);
91+
}
3592
}
3693

37-
private void FavoriteChanged(object? sender, string[] e) => SetFavoriteCollection();
94+
private void FavoriteChanged(object? sender, string[] e) => LoadFavorites();
3895

39-
private void SetFavoriteCollection()
96+
private void LoadFavorites()
4097
{
41-
string[] favorites = ResizeArray(_favoriteManager.Favorites.AsEnumerable().Reverse().ToArray(), 9);
42-
if (favorites.Length == Favorites?.Count && favorites.All(x => Favorites.Select(y => y.Url).Contains(x)))
43-
return;
98+
try
99+
{
100+
string[] favorites = ResizeArray(_favoriteManager.Favorites.AsEnumerable().Reverse().ToArray(), 9);
101+
bool needsUpdate = Favorites == null ||
102+
favorites.Length != Favorites.Count ||
103+
!favorites.All(x => Favorites.Select(y => y.Url).Contains(x));
104+
105+
if (!needsUpdate)
106+
return;
107+
Application.Current.Dispatcher.Invoke(() =>
108+
{
109+
try
110+
{
111+
ObservableCollection<ComicVM> newFavorites = new();
112+
113+
foreach (string url in favorites)
114+
{
115+
WebsiteScraper.WebsiteUtilities.Website? website = _websiteManager.GetWebsite(new Uri(url).Host);
116+
if (website != null)
117+
{
118+
Comic comic = new(url, url, website);
119+
ComicVM comicVM = new(comic);
120+
if (!string.IsNullOrEmpty(comicVM.Website))
121+
{
122+
newFavorites.Add(comicVM);
123+
}
124+
}
125+
}
44126

45-
Favorites = new ObservableCollection<ComicVM>(favorites.Select(x => new ComicVM(new Comic(x, x, _websiteManagaer.GetWebsite(new Uri(x).Host) ?? new()))).Where(x => !string.IsNullOrEmpty(x.Website)));
46-
FavoritesVisible = Favorites.Any();
127+
Favorites = newFavorites;
128+
FavoritesVisible = Favorites.Any();
129+
}
130+
catch (Exception ex)
131+
{
132+
Debug.WriteLine($"Error creating favorite ComicVMs: {ex.Message}");
133+
}
134+
});
135+
}
136+
catch (Exception ex)
137+
{
138+
Debug.WriteLine($"Error in LoadFavorites: {ex.Message}");
139+
}
47140
}
48141

49-
private string[] ResizeArray(string[] array, int length)
142+
private static string[] ResizeArray(string[] array, int length)
50143
{
51144
if (array.Length > length)
52145
Array.Resize(ref array, length);
53146
return array;
54147
}
55148

56-
private void SetWebsiteCollection() => Websites = new ObservableCollection<HomeWebsiteVM>(_websiteManagaer.Websites.Select(w => new HomeWebsiteVM(w)));
149+
private void SetWebsiteCollection()
150+
{
151+
try
152+
{
153+
ObservableCollection<HomeWebsiteVM> newWebsites = [];
154+
foreach (WebsiteScraper.WebsiteUtilities.Website website in _websiteManager.Websites)
155+
newWebsites.Add(new HomeWebsiteVM(website));
156+
Websites = newWebsites;
157+
}
158+
catch (Exception ex)
159+
{
160+
Debug.WriteLine($"Error in SetWebsiteCollection: {ex.Message}");
161+
}
162+
}
163+
164+
private void RefreshWebsiteData()
165+
{
166+
try
167+
{
168+
foreach (HomeWebsiteVM websiteVM in Websites)
169+
websiteVM.RefreshData();
170+
171+
}
172+
catch (Exception ex)
173+
{
174+
Debug.WriteLine($"Error in RefreshWebsiteData: {ex.Message}");
175+
}
176+
}
57177
}
58-
}
178+
}

0 commit comments

Comments
 (0)