Skip to content

Commit 2a89bb2

Browse files
committed
Add splash screen and improve startup loading, some wording changes
1 parent 0addec9 commit 2a89bb2

12 files changed

Lines changed: 222 additions & 109 deletions

FluentDL/App.xaml.cs

Lines changed: 10 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
using System.Diagnostics;
2+
using System.Text;
3+
using System.Threading;
4+
15
using FluentDL.Activation;
26
using FluentDL.Contracts.Services;
37
using FluentDL.Core.Contracts.Services;
@@ -8,12 +12,12 @@
812
using FluentDL.Services;
913
using FluentDL.ViewModels;
1014
using FluentDL.Views;
15+
1116
using Microsoft.Extensions.DependencyInjection;
1217
using Microsoft.Extensions.Hosting;
1318
using Microsoft.UI.Xaml;
14-
using System.Diagnostics;
15-
using System.Text;
16-
using System.Threading;
19+
using Microsoft.UI.Xaml.Controls;
20+
1721
using Windows.Graphics.Display;
1822

1923
namespace FluentDL;
@@ -89,6 +93,8 @@ public App()
8993
services.AddTransient<LocalExplorerPage>();
9094
services.AddTransient<QueueViewModel>();
9195
services.AddTransient<QueuePage>();
96+
services.AddTransient<SplashScreenViewModel>();
97+
services.AddTransient<SplashScreenPage>();
9298
services.AddTransient<SearchViewModel>();
9399
services.AddTransient<Search>();
94100
services.AddTransient<ShellPage>();
@@ -100,12 +106,6 @@ public App()
100106
}).Build();
101107
App.GetService<IAppNotificationService>().Initialize();
102108
UnhandledException += App_UnhandledException;
103-
MainWindow.Closed += MainWindow_Closed;
104-
}
105-
106-
private void MainWindow_Closed(object sender, WindowEventArgs args)
107-
{
108-
QueueSaver.Close();
109109
}
110110

111111
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
@@ -116,54 +116,9 @@ private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledEx
116116

117117
protected async override void OnLaunched(LaunchActivatedEventArgs args)
118118
{
119-
await Task.Delay(250);
120119
base.OnLaunched(args);
121120
// App.GetService<IAppNotificationService>().Show(string.Format("AppNotificationSamplePayload".GetLocalized(), AppContext.BaseDirectory));
122121

123122
await App.GetService<IActivationService>().ActivateAsync(args);
124-
125-
if (await SettingsViewModel.GetSetting<bool?>(SettingsViewModel.FirstRun) ?? true)
126-
await SettingsViewModel.SetMissingDefaults();
127-
128-
await QueueViewModel.UpdateShortcutVisibility();
129-
try
130-
{
131-
// Fetch previous command list
132-
await LocalCommands.Init();
133-
134-
// Initialize FFMpeg
135-
await FFmpegRunner.Initialize();
136-
137-
// Initialize environment variables
138-
await KeyReader.Initialize();
139-
140-
// Initialize api objects
141-
var localSettings = App.GetService<ILocalSettingsService>();
142-
143-
// Run seperate thread for synchronous Qobuz initialization
144-
Thread thread = new Thread(() =>
145-
{
146-
var qobuzEmail = DPAPIHelper.Decrypt(localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzEmail).GetAwaiter().GetResult() ?? "");
147-
var qobuzPassword = DPAPIHelper.Decrypt(localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzPassword).GetAwaiter().GetResult() ?? "");
148-
var qobuzId = localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzId).GetAwaiter().GetResult();
149-
var qobuzToken = localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzToken).GetAwaiter().GetResult();
150-
var qobuzAppId = localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzAppId).GetAwaiter().GetResult();
151-
var qobuzAppSecret = localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzAppSecret).GetAwaiter().GetResult();
152-
QobuzApi.Initialize(qobuzEmail, qobuzPassword, qobuzId, qobuzToken, qobuzAppId, qobuzAppSecret);
153-
});
154-
thread.Priority = ThreadPriority.Highest;
155-
thread.Start();
156-
157-
158-
await SpotifyApi.Initialize(await localSettings.ReadSettingAsync<string>(SettingsViewModel.SpotifyClientId), await localSettings.ReadSettingAsync<string>(SettingsViewModel.SpotifyClientSecret));
159-
await DeezerApi.InitDeezerClient(await localSettings.ReadSettingAsync<string>(SettingsViewModel.DeezerARL));
160-
await QueueViewModel.LoadSaveQueue();
161-
162-
QueueSaver.Init();
163-
}
164-
catch (Exception e)
165-
{
166-
Debug.WriteLine(e);
167-
}
168123
}
169-
}
124+
}

FluentDL/Services/ActivationService.cs

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using FluentDL.Activation;
22
using FluentDL.Contracts.Services;
3+
using FluentDL.Helpers;
4+
using FluentDL.ViewModels;
35
using FluentDL.Views;
46

57
using Microsoft.UI.Xaml;
@@ -24,23 +26,32 @@ public ActivationService(ActivationHandler<LaunchActivatedEventArgs> defaultHand
2426

2527
public async Task ActivateAsync(object activationArgs)
2628
{
27-
// Execute tasks before activation.
28-
await InitializeAsync();
29-
30-
// Set the MainWindow Content.
29+
// Show splash screen immediately
30+
var splashScreen = App.GetService<SplashScreenPage>();
3131
if (App.MainWindow.Content == null)
3232
{
33-
_shell = App.GetService<ShellPage>();
34-
App.MainWindow.Content = _shell ?? new Frame();
33+
App.MainWindow.Content = splashScreen;
34+
App.MainWindow.Activate();
3535
}
3636

37-
// Handle activation via ActivationHandlers.
37+
// Execute tasks before activation
38+
await InitializeAsync();
39+
40+
// Initialize shell behind splash screen
41+
_shell = App.GetService<ShellPage>();
42+
43+
// Handle activation via ActivationHandlers
3844
await HandleActivationAsync(activationArgs);
3945

40-
// Activate the MainWindow.
46+
// Initialize APIs
47+
await InitAPIs();
48+
49+
// Switch from splash screen to shell
50+
App.MainWindow.Content = _shell ?? new Frame();
4151
App.MainWindow.Activate();
52+
App.MainWindow.Closed += (s, e) => QueueSaver.Close();
4253

43-
// Execute tasks after activation.
54+
// Execute tasks after activation
4455
await StartupAsync();
4556
}
4657

@@ -70,4 +81,48 @@ private async Task StartupAsync()
7081
await _themeSelectorService.SetRequestedThemeAsync();
7182
await Task.CompletedTask;
7283
}
84+
85+
private async Task InitAPIs()
86+
{
87+
if (await SettingsViewModel.GetSetting<bool?>(SettingsViewModel.FirstRun) ?? true)
88+
await SettingsViewModel.SetMissingDefaults();
89+
90+
await QueueViewModel.UpdateShortcutVisibility();
91+
try
92+
{
93+
// Fetch previous command list
94+
await LocalCommands.Init();
95+
96+
// Initialize FFMpeg
97+
await FFmpegRunner.Initialize();
98+
99+
// Initialize environment variables
100+
await KeyReader.Initialize();
101+
102+
// Initialize api objects
103+
var localSettings = App.GetService<ILocalSettingsService>();
104+
105+
var qobuzEmail = DPAPIHelper.Decrypt(await localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzEmail) ?? "");
106+
var qobuzPassword = DPAPIHelper.Decrypt(await localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzPassword) ?? "");
107+
var qobuzId = await localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzId);
108+
var qobuzToken = await localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzToken);
109+
var qobuzAppId = await localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzAppId);
110+
var qobuzAppSecret = await localSettings.ReadSettingAsync<string>(SettingsViewModel.QobuzAppSecret);
111+
var spotifyClientId = await localSettings.ReadSettingAsync<string>(SettingsViewModel.SpotifyClientId);
112+
var spotifyClientSecret = await localSettings.ReadSettingAsync<string>(SettingsViewModel.SpotifyClientSecret);
113+
var deezerArl = await localSettings.ReadSettingAsync<string>(SettingsViewModel.DeezerARL);
114+
await Task.WhenAll(
115+
Task.Run(() => QobuzApi.Initialize(qobuzEmail, qobuzPassword, qobuzId, qobuzToken, qobuzAppId, qobuzAppSecret)),
116+
Task.Run(() => SpotifyApi.Initialize(spotifyClientId, spotifyClientSecret)),
117+
DeezerApi.InitDeezerClient(deezerArl)
118+
);
119+
await QueueViewModel.LoadSaveQueue();
120+
121+
QueueSaver.Init();
122+
}
123+
catch (Exception e)
124+
{
125+
Debug.WriteLine(e);
126+
}
127+
}
73128
}

FluentDL/Services/PageService.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using CommunityToolkit.Mvvm.ComponentModel;
2+
23
using FluentDL.Contracts.Services;
34
using FluentDL.ViewModels;
45
using FluentDL.Views;
6+
57
using Microsoft.UI.Xaml.Controls;
68

79
namespace FluentDL.Services;
@@ -17,6 +19,7 @@ public PageService()
1719
Configure<LocalExplorerViewModel, LocalExplorerPage>();
1820
Configure<ContentGridDetailViewModel, ContentGridDetailPage>();
1921
Configure<SettingsViewModel, SettingsPage>();
22+
Configure<SplashScreenViewModel, SplashScreenPage>();
2023
}
2124

2225
public Type GetPageType(string key)
@@ -55,4 +58,4 @@ private void Configure<VM, V>()
5558
_pages.Add(key, type);
5659
}
5760
}
58-
}
61+
}

FluentDL/Services/SpotifyApi.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ public SpotifyApi()
3434

3535
}
3636

37-
public static async Task Initialize(string? clientId, string? clientSecret)
37+
public static async Task InitializeAsync(string? clientId, string? clientSecret)
38+
{
39+
await Task.Run(() => Initialize(clientId, clientSecret));
40+
}
41+
public static void Initialize(string? clientId, string? clientSecret)
3842
{
3943
IsInitialized = false;
4044

@@ -43,7 +47,7 @@ public static async Task Initialize(string? clientId, string? clientSecret)
4347
{
4448
try
4549
{
46-
spotify = await Task.Run(() => new SpotifyClient(config.WithAuthenticator(new ClientCredentialsAuthenticator(clientId, clientSecret))));
50+
spotify = new SpotifyClient(config.WithAuthenticator(new ClientCredentialsAuthenticator(clientId, clientSecret)));
4751
IsInitialized = true;
4852
return;
4953
}
@@ -52,19 +56,22 @@ public static async Task Initialize(string? clientId, string? clientSecret)
5256
Debug.WriteLine("Failed to initialize Spotify API: " + e.Message);
5357
}
5458
}
55-
59+
5660
// If clientId and clientSecret are not provided, try to get from browser
5761
try
5862
{
59-
spotify = await Task.Run(() => new SpotifyClient(config.WithAuthenticator(new EmbedAuthenticator())));
63+
spotify = new SpotifyClient(config.WithAuthenticator(new EmbedAuthenticator()));
6064
IsInitialized = true;
6165
return;
62-
} catch (Exception e) {
66+
}
67+
catch (Exception e)
68+
{
6369
Debug.WriteLine("Failed to get access token: " + e.Message);
6470
}
65-
71+
6672
// If still not initialized, try to get bundled keys
67-
try {
73+
try
74+
{
6875
var idList = KeyReader.GetValues("spot_id");
6976
var secretList = KeyReader.GetValues("spot_secret");
7077

@@ -74,15 +81,17 @@ public static async Task Initialize(string? clientId, string? clientSecret)
7481
var id = idList[randIdx];
7582
var secret = secretList[randIdx];
7683

77-
if (string.IsNullOrWhiteSpace(id) || string.IsNullOrWhiteSpace(secret))
84+
if (string.IsNullOrWhiteSpace(id) || string.IsNullOrWhiteSpace(secret))
7885
{
7986
throw new Exception("invalid/empty bundled key in list");
8087
}
8188

82-
spotify = await Task.Run(() => new SpotifyClient(config.WithAuthenticator(new ClientCredentialsAuthenticator(id, secret))));
89+
spotify = new SpotifyClient(config.WithAuthenticator(new ClientCredentialsAuthenticator(id, secret)));
8390
IsInitialized = true;
8491
}
85-
} catch (Exception e) {
92+
}
93+
catch (Exception e)
94+
{
8695
Debug.WriteLine("Failed to initialize Spotify API: " + e.Message);
8796
}
8897
}

FluentDL/Strings/en-us/Resources.resw

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,7 @@
182182
&lt;/toast&gt;
183183
</value>
184184
</data>
185-
</root>
185+
<data name="Shell_SplashScreen.Content" xml:space="preserve">
186+
<value>SplashScreen</value>
187+
</data>
188+
</root>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
3+
namespace FluentDL.ViewModels;
4+
5+
public partial class SplashScreenViewModel : ObservableRecipient
6+
{
7+
private string _loadingText = string.Empty;
8+
9+
public string LoadingText
10+
{
11+
get => _loadingText;
12+
set => SetProperty(ref _loadingText, value);
13+
}
14+
15+
public SplashScreenViewModel()
16+
{
17+
}
18+
}

0 commit comments

Comments
 (0)