Skip to content

Commit 1cf16f7

Browse files
committed
Feature: Add 'login' cancel functionality.
1 parent 2f6a388 commit 1cf16f7

File tree

3 files changed

+66
-19
lines changed

3 files changed

+66
-19
lines changed

G33kShell.Desktop/ViewModels/ShellViewModel.cs

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
using G33kShell.Desktop.Terminal;
2626
using G33kShell.Desktop.Terminal.Controls;
2727
using SkiaSharp;
28+
using Border = G33kShell.Desktop.Console.Controls.Border;
29+
using Image = G33kShell.Desktop.Console.Controls.Image;
30+
using ProgressBar = G33kShell.Desktop.Console.Controls.ProgressBar;
31+
using TextBlock = G33kShell.Desktop.Console.Controls.TextBlock;
2832

2933
// ReSharper disable UnusedMember.Local
3034

@@ -41,6 +45,7 @@ public class ShellViewModel : ViewModelBase, IDisposable
4145
{
4246
private TerminalState m_terminalState;
4347
private ScreensaverControl m_screensaverControl;
48+
private bool m_cancelLogin;
4449

4550
/// <summary>
4651
/// Occurs when a request is made to reveal the current working directory.
@@ -62,10 +67,28 @@ public ShellViewModel(SkinBase skin)
6267
WindowManager = new WindowManager(100, 38, skin);
6368
_ = StartAsync();
6469
}
65-
70+
71+
public void CancelLogin() => m_cancelLogin = true;
72+
6673
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
6774
private async Task StartAsync()
6875
{
76+
#if !DEBUG
77+
// Start the 'sign in' face-finding background task.
78+
var signInTask = CaptureFaceAsync();
79+
80+
// Log-in awesomeness.
81+
if (!m_cancelLogin)
82+
await BiosCheckAsync();
83+
if (!m_cancelLogin)
84+
await LoadOsAsync();
85+
86+
if (!m_cancelLogin)
87+
{
88+
var signInResult = await signInTask;
89+
await LogInAsync(signInResult);
90+
}
91+
#endif
6992

7093
// Run the terminal.
7194
_ = Task.Run(RunTerminal);
@@ -186,10 +209,19 @@ private async Task BiosCheckAsync()
186209
})
187210
.AddChild(biosText);
188211

189-
await Task.Run(() => biosText.Waiter.Wait());
190-
await Task.Delay(TimeSpan.FromSeconds(1));
212+
if (!m_cancelLogin)
213+
await Task.Run(() =>
214+
{
215+
while (!m_cancelLogin && !biosText.Waiter.Wait(100))
216+
{
217+
// Wait.
218+
}
219+
});
220+
if (!m_cancelLogin)
221+
await Task.Delay(TimeSpan.FromSeconds(1));
191222
await WindowManager.Root.ClearAsync(ClearTransition.Immediate);
192-
await Task.Delay(TimeSpan.FromSeconds(2));
223+
if (!m_cancelLogin)
224+
await Task.Delay(TimeSpan.FromSeconds(2));
193225
}
194226

195227
private async Task LoadOsAsync()
@@ -221,25 +253,28 @@ private async Task LoadOsAsync()
221253
});
222254

223255
// Animate the 'Penetration' process.
224-
await new Animation(
225-
TimeSpan.FromSeconds(2),
226-
TimeSpan.FromSeconds(5),
227-
f =>
228-
{
229-
WindowManager.Find<ProgressBar>("LogoProgress").Progress = (int)(f * 100);
230-
return true;
231-
})
232-
.StartAsync();
256+
if (!m_cancelLogin)
257+
await new Animation(
258+
TimeSpan.FromSeconds(2),
259+
TimeSpan.FromSeconds(5),
260+
f =>
261+
{
262+
WindowManager.Find<ProgressBar>("LogoProgress").Progress = (int) (f * 100);
263+
return !m_cancelLogin;
264+
})
265+
.StartAsync();
233266

234267
// Clear the screen with the Explode transition.
235-
await Task.Delay(TimeSpan.FromSeconds(2));
268+
if (!m_cancelLogin)
269+
await Task.Delay(TimeSpan.FromSeconds(2));
236270
await WindowManager.Root.ClearAsync(ClearTransition.Explode);
237-
await Task.Delay(TimeSpan.FromSeconds(1));
271+
if (!m_cancelLogin)
272+
await Task.Delay(TimeSpan.FromSeconds(1));
238273
}
239274

240275
private async Task LogInAsync((SKBitmap Image, FaceFinder.FaceDetails Face)? faceAnalysis)
241276
{
242-
if (faceAnalysis == null)
277+
if (faceAnalysis == null || m_cancelLogin)
243278
return;
244279

245280
// 'Sign in' face analysis...
@@ -307,7 +342,7 @@ private async Task LogInAsync((SKBitmap Image, FaceFinder.FaceDetails Face)? fac
307342
featureBoxes.Add(border);
308343
}
309344

310-
for (var i = 0; i < 8; i++)
345+
for (var i = 0; i < 8 && !m_cancelLogin; i++)
311346
{
312347
featureBoxes.Shuffle();
313348
foreach (var featureBox in featureBoxes)
@@ -333,9 +368,11 @@ private async Task LogInAsync((SKBitmap Image, FaceFinder.FaceDetails Face)? fac
333368
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center
334369
});
335370

336-
await Task.Delay(TimeSpan.FromSeconds(4));
371+
if (!m_cancelLogin)
372+
await Task.Delay(TimeSpan.FromSeconds(4));
337373
await WindowManager.Root.ClearAsync(ClearTransition.Explode);
338-
await Task.Delay(TimeSpan.FromSeconds(1));
374+
if (!m_cancelLogin)
375+
await Task.Delay(TimeSpan.FromSeconds(1));
339376
}
340377

341378
private static FaceFinder CreateFaceFinder() =>

G33kShell.Desktop/Views/App.axaml.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
using Avalonia.Controls;
1616
using Avalonia.Controls.ApplicationLifetimes;
1717
using Avalonia.Markup.Xaml;
18+
using Avalonia.Remote.Protocol.Input;
1819
using CSharp.Core.Extensions;
1920
using G33kShell.Desktop.Skins;
2021
using G33kShell.Desktop.Terminal;
2122
using G33kShell.Desktop.Terminal.Commands;
2223
using G33kShell.Desktop.ViewModels;
24+
using PhysicalKey = Avalonia.Input.PhysicalKey;
2325

2426
namespace G33kShell.Desktop.Views;
2527

@@ -43,6 +45,12 @@ public override void OnFrameworkInitializationCompleted()
4345
{
4446
DataContext = viewModel
4547
};
48+
desktop.MainWindow.KeyDown += (_, args) =>
49+
{
50+
if (args.PhysicalKey == PhysicalKey.Escape)
51+
viewModel.CancelLogin();
52+
};
53+
4654
desktop.Exit += (_, _) => viewModel.Dispose();
4755

4856
if (!Design.IsDesignMode)

G33kShell.sln.DotSettings.user

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInterop_002EGenerated_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F4f9cf1255afde8a1351295998398dee92518566f1fef855268644112b41146_003FInterop_002EGenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1818
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonSerializerInternalReader_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F29ea32a76b2a6b8eb246f247df6a6a86d887384b4c31db2a35effccdd86c24_003FJsonSerializerInternalReader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
1919
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJsonSerializerInternalWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe2e3d26278e439d44964729238a685ad58d3189abf8fb84cdfe34b893a290a2_003FJsonSerializerInternalWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
20+
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKeyEventArgs_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F88503cfcfb88a0d7e5e2152c886575383acf15656d45fb9867891e044208c71_003FKeyEventArgs_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
21+
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AKey_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Ffc7b418211762675fec7a18cc5d829af5c1fc54bfd338d3f3587999c53bc90_003FKey_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
2022
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALinkedList_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F74b2ad5ea433da71a378b52e2fe95faf8d8772e48485484656e951f5625678_003FLinkedList_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
2123
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fe747192abb38e2df82cbdb37e721567726f559914a7b81f8b26ba537de632f4_003FList_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
2224
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMainViewModel_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F99871328d5178f48c02acf70e2f680364e8cbd52ba45e1da396723dd1278a6c5_003FMainViewModel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

0 commit comments

Comments
 (0)