using Avalonia; using CommunityToolkit.Mvvm.ComponentModel; using InkForge.Data; using InkForge.Desktop.Data.Options; using InkForge.Desktop.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; namespace InkForge.Desktop.Managers; public partial class WorkspaceManager(IServiceProvider serviceProvider) : ObservableObject { private readonly IServiceProvider _serviceProvider = serviceProvider; [ObservableProperty] private Workspace? _workspace; public ValueTask CloseWorkspace() { Workspace?.Dispose(); Workspace = null; return ValueTask.CompletedTask; } public async ValueTask OpenWorkspace(string path, bool createFile = false) { await CloseWorkspace().ConfigureAwait(false); if (await CreateLocalWorkspace(path, createFile).ConfigureAwait(false) is { } workspace) { Workspace = workspace; } } private async ValueTask CreateLocalWorkspace(string path, bool createFile) { FileInfo file = new(path); if (!(createFile || file.Exists)) { return null; } file.Directory!.Create(); IServiceScope? scope = null; IWorkspaceContext workspaceContext; try { scope = _serviceProvider.CreateScope(); var serviceProvider = scope.ServiceProvider; var options = serviceProvider.GetRequiredService(); options.DbPath = path; workspaceContext = serviceProvider.GetRequiredService(); workspaceContext.Workspace = new Workspace(scope) { Name = Path.GetFileNameWithoutExtension(file.Name), Options = options, }; var dbFactory = serviceProvider.GetRequiredService>(); await using var dbContext = await dbFactory.CreateDbContextAsync().ConfigureAwait(false); var db = dbContext.Database; if ((await db.GetPendingMigrationsAsync().ConfigureAwait(false)).Any()) { if ((await db.GetAppliedMigrationsAsync().ConfigureAwait(false)).Any()) { file.CopyTo(Path.ChangeExtension(file.FullName, $"{DateTime.Now:s}{file.Extension}")); } await db.MigrateAsync().ConfigureAwait(false); } await serviceProvider.GetRequiredService().Load().ConfigureAwait(false); scope = null; } catch (Exception) { // Show Error through TopLevels.ActiveTopLevel return null; } finally { scope?.Dispose(); } return workspaceContext.Workspace; } }