Skip to content

Commit

Permalink
Convert to block-scoped namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
BobLd committed May 21, 2024
1 parent 99aed3a commit 5feb148
Show file tree
Hide file tree
Showing 7 changed files with 426 additions and 419 deletions.
35 changes: 18 additions & 17 deletions Caly.Android/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,25 @@
using Avalonia.Android;
using Caly.Core;

namespace Caly.Android;

[Activity(
Label = "Caly.Android",
Theme = "@style/MyTheme.NoActionBar",
Icon = "@drawable/icon",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
public class MainActivity : AvaloniaMainActivity<App>
namespace Caly.Android
{
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
[Activity(
Label = "Caly.Android",
Theme = "@style/MyTheme.NoActionBar",
Icon = "@drawable/icon",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)]
public class MainActivity : AvaloniaMainActivity<App>
{
return base.CustomizeAppBuilder(builder)
.WithInterFont()
.UseSkia()
.With(new AndroidPlatformOptions()
{
RenderingMode = new[] { AndroidRenderingMode.Software }
});
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
.WithInterFont()
.UseSkia()
.With(new AndroidPlatformOptions()
{
RenderingMode = new[] { AndroidRenderingMode.Software }
});
}
}
}
283 changes: 142 additions & 141 deletions Caly.Core/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,196 +30,197 @@
using Caly.Core.Views;
using Microsoft.Extensions.DependencyInjection;

namespace Caly.Core;

public partial class App : Application
namespace Caly.Core
{
private readonly FilePipeStream _pipeServer = new();
private readonly CancellationTokenSource listeningToFilesCts = new();
private Task? listeningToFiles;
public partial class App : Application
{
private readonly FilePipeStream _pipeServer = new();
private readonly CancellationTokenSource listeningToFilesCts = new();
private Task? listeningToFiles;

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private IPdfDocumentsService _pdfDocumentsService;
private IPdfDocumentsService _pdfDocumentsService;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

public new static App? Current => Application.Current as App;
public new static App? Current => Application.Current as App;

/// <summary>
/// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
/// </summary>
public IServiceProvider? Services { get; private set; }
/// <summary>
/// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
/// </summary>
public IServiceProvider? Services { get; private set; }

public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted()
{
// Line below is needed to remove Avalonia data validation.
// Without this line you will get duplicate validations from both Avalonia and CT
BindingPlugins.DataValidators.RemoveAt(0);
public override void OnFrameworkInitializationCompleted()
{
// Line below is needed to remove Avalonia data validation.
// Without this line you will get duplicate validations from both Avalonia and CT
BindingPlugins.DataValidators.RemoveAt(0);

// Initialise dependencies
var services = new ServiceCollection();
// Initialise dependencies
var services = new ServiceCollection();

if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
DataContext = new MainViewModel()
};
desktop.MainWindow = new MainWindow
{
DataContext = new MainViewModel()
};

services.AddSingleton(_ => (Visual)desktop.MainWindow);
desktop.Startup += Desktop_Startup;
desktop.Exit += Desktop_Exit;
services.AddSingleton(_ => (Visual)desktop.MainWindow);
desktop.Startup += Desktop_Startup;
desktop.Exit += Desktop_Exit;
#if DEBUG
desktop.MainWindow.RendererDiagnostics.DebugOverlays = Avalonia.Rendering.RendererDebugOverlays.RenderTimeGraph;
desktop.MainWindow.RendererDiagnostics.DebugOverlays = Avalonia.Rendering.RendererDebugOverlays.RenderTimeGraph;
#endif
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
{
singleViewPlatform.MainView = new MainView
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
{
DataContext = new MainViewModel()
};
services.AddSingleton(_ => (Visual)singleViewPlatform.MainView);
}
singleViewPlatform.MainView = new MainView
{
DataContext = new MainViewModel()
};
services.AddSingleton(_ => (Visual)singleViewPlatform.MainView);
}

services.AddSingleton<IFilesService, FilesService>();
services.AddSingleton<IDialogService, DialogService>();
services.AddSingleton<IClipboardService, ClipboardService>();
services.AddSingleton<IPdfDocumentsService, PdfDocumentsService>();
services.AddTransient<IPdfService, PdfPigPdfService>();
services.AddSingleton<IFilesService, FilesService>();
services.AddSingleton<IDialogService, DialogService>();
services.AddSingleton<IClipboardService, ClipboardService>();
services.AddSingleton<IPdfDocumentsService, PdfDocumentsService>();
services.AddTransient<IPdfService, PdfPigPdfService>();

Services = services.BuildServiceProvider();
Services = services.BuildServiceProvider();

// We need to make sure IPdfDocumentsService singleton is initiated in UI thread
// We need to make sure IPdfDocumentsService singleton is initiated in UI thread
#pragma warning disable CS8601 // Possible null reference assignment.
_pdfDocumentsService = Services.GetRequiredService<IPdfDocumentsService>();
_pdfDocumentsService = Services.GetRequiredService<IPdfDocumentsService>();
#pragma warning restore CS8601 // Possible null reference assignment.

// TODO - Check https://github.com/AvaloniaUI/Avalonia/commit/0e014f9cb627d99fb4e1afa389b4c073c836e9b6
// TODO - Check https://github.com/AvaloniaUI/Avalonia/commit/0e014f9cb627d99fb4e1afa389b4c073c836e9b6

base.OnFrameworkInitializationCompleted();
}

private async void Desktop_Startup(object? sender, ControlledApplicationLifetimeStartupEventArgs e)
{
listeningToFiles = Task.Run(ListenToIncomingFiles); // Start listening

if (e.Args.Length == 0)
{
return;
base.OnFrameworkInitializationCompleted();
}

await Task.Run(() => OpenDoc(e.Args[0], CancellationToken.None));
}

private void Desktop_Exit(object? sender, ControlledApplicationLifetimeExitEventArgs e)
{
listeningToFilesCts.Cancel();
GC.KeepAlive(listeningToFiles);

if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
private async void Desktop_Startup(object? sender, ControlledApplicationLifetimeStartupEventArgs e)
{
desktop.Startup -= Desktop_Startup;
desktop.Exit -= Desktop_Exit;
}
}
listeningToFiles = Task.Run(ListenToIncomingFiles); // Start listening

private async Task ListenToIncomingFiles()
{
Debug.ThrowOnUiThread();
if (e.Args.Length == 0)
{
return;
}

try
{
await Parallel.ForEachAsync(_pipeServer.ReceivePathAsync(listeningToFilesCts.Token),
listeningToFilesCts.Token,
async (path, ct) => await OpenDoc(path, ct));
await Task.Run(() => OpenDoc(e.Args[0], CancellationToken.None));
}
catch (OperationCanceledException)
{
// No op
}
catch (Exception ex)

private void Desktop_Exit(object? sender, ControlledApplicationLifetimeExitEventArgs e)
{
// Critical error...
ShowExceptionWindowSafely(ex);
Debug.WriteExceptionToFile(ex);
throw;
listeningToFilesCts.Cancel();
GC.KeepAlive(listeningToFiles);

if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.Startup -= Desktop_Startup;
desktop.Exit -= Desktop_Exit;
}
}
finally

private async Task ListenToIncomingFiles()
{
await _pipeServer.DisposeAsync();
}
}
Debug.ThrowOnUiThread();

private async Task OpenDoc(string? path, CancellationToken token)
{
Debug.ThrowOnUiThread();
try
{
await Parallel.ForEachAsync(_pipeServer.ReceivePathAsync(listeningToFilesCts.Token),
listeningToFilesCts.Token,
async (path, ct) => await OpenDoc(path, ct));
}
catch (OperationCanceledException)
{
// No op
}
catch (Exception ex)
{
// Critical error...
ShowExceptionWindowSafely(ex);
Debug.WriteExceptionToFile(ex);
throw;
}
finally
{
await _pipeServer.DisposeAsync();
}
}

try
private async Task OpenDoc(string? path, CancellationToken token)
{
if (string.IsNullOrEmpty(path) || !File.Exists(path))
Debug.ThrowOnUiThread();

try
{
var dialogService = Services?.GetRequiredService<IDialogService>();
if (dialogService is not null)
if (string.IsNullOrEmpty(path) || !File.Exists(path))
{
Dispatcher.UIThread.Post(() => dialogService.ShowNotification("Cannot open file",
"The file does not exist or the path is invalid.", NotificationType.Error));
}
var dialogService = Services?.GetRequiredService<IDialogService>();
if (dialogService is not null)
{
Dispatcher.UIThread.Post(() => dialogService.ShowNotification("Cannot open file",
"The file does not exist or the path is invalid.", NotificationType.Error));
}

// TODO - Log
// TODO - Log

return;
}
return;
}

await _pdfDocumentsService.OpenLoadDocument(path, token);
}
catch (Exception ex)
{
ShowExceptionNotificationSafely(ex);
Debug.WriteExceptionToFile(ex);
await _pdfDocumentsService.OpenLoadDocument(path, token);
}
catch (Exception ex)
{
ShowExceptionNotificationSafely(ex);
Debug.WriteExceptionToFile(ex);
}
}
}

private void ShowExceptionNotificationSafely(Exception? ex)
{
Dispatcher.UIThread.Post(() =>
private void ShowExceptionNotificationSafely(Exception? ex)
{
try
Dispatcher.UIThread.Post(() =>
{
if (ex is null) return;
try
{
if (ex is null) return;

var dialogService = Services?.GetRequiredService<IDialogService>();
if (dialogService is not null)
var dialogService = Services?.GetRequiredService<IDialogService>();
if (dialogService is not null)
{
Dispatcher.UIThread.Post(() => dialogService.ShowNotification("Error", ex.Message, NotificationType.Error));
}
}
catch
{
Dispatcher.UIThread.Post(() => dialogService.ShowNotification("Error", ex.Message, NotificationType.Error));
// No op
}
}
catch
{
// No op
}
});
}
});
}

private void ShowExceptionWindowSafely(Exception? ex)
{
Dispatcher.UIThread.Post(() =>
private void ShowExceptionWindowSafely(Exception? ex)
{
try
Dispatcher.UIThread.Post(() =>
{
if (ex is null) return;
try
{
if (ex is null) return;

var dialogService = Services?.GetRequiredService<IDialogService>();
dialogService?.ShowExceptionWindow(ex);
}
catch
{
// No op
}
});
var dialogService = Services?.GetRequiredService<IDialogService>();
dialogService?.ShowExceptionWindow(ex);
}
catch
{
// No op
}
});
}
}
}
Loading

0 comments on commit 5feb148

Please sign in to comment.