Replace ReactiveUI
This commit is contained in:
parent
43b4d50e43
commit
5584ab4ec8
41 changed files with 472 additions and 1013 deletions
|
|
@ -5,13 +5,15 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia" Version="11.0.10" />
|
<PackageVersion Include="Avalonia" Version="11.0.10" />
|
||||||
|
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="11.0.6" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.0.10" />
|
||||||
<PackageVersion Include="Avalonia.Fonts.Inter" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Fonts.Inter" Version="11.0.10" />
|
||||||
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.0.10" />
|
|
||||||
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.0.10" />
|
||||||
|
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageVersion Include="Dock.Avalonia" Version="11.0.0.7" />
|
<PackageVersion Include="Dock.Avalonia" Version="11.0.0.7" />
|
||||||
<PackageVersion Include="Dock.Model.ReactiveUI" Version="11.0.0.7" />
|
<PackageVersion Include="Dock.Model.Mvvm" Version="11.0.0.7" />
|
||||||
|
<PackageVersion Include="DynamicData" Version="8.4.1" />
|
||||||
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
|
||||||
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
|
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
|
||||||
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.3" />
|
<PackageVersion Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.3" />
|
||||||
|
|
@ -26,6 +28,7 @@
|
||||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" />
|
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" />
|
||||||
<PackageVersion Include="SmartFormat" Version="3.3.2" />
|
<PackageVersion Include="SmartFormat" Version="3.3.2" />
|
||||||
|
<PackageVersion Include="Splat" Version="15.0.1" />
|
||||||
<PackageVersion Include="Splat.Microsoft.Extensions.DependencyInjection" Version="14.8.12" />
|
<PackageVersion Include="Splat.Microsoft.Extensions.DependencyInjection" Version="14.8.12" />
|
||||||
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<FluentTheme />
|
<FluentTheme />
|
||||||
|
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
|
||||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" />
|
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" />
|
||||||
<DockFluentTheme />
|
<DockFluentTheme />
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
using Splat;
|
using Splat;
|
||||||
using Splat.Microsoft.Extensions.DependencyInjection;
|
using Splat.Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
|
@ -47,7 +45,6 @@ public partial class App : Application
|
||||||
|
|
||||||
services.UseMicrosoftDependencyResolver();
|
services.UseMicrosoftDependencyResolver();
|
||||||
Locator.CurrentMutable.InitializeSplat();
|
Locator.CurrentMutable.InitializeSplat();
|
||||||
Locator.CurrentMutable.InitializeReactiveUI();
|
|
||||||
|
|
||||||
services.AddInkForge();
|
services.AddInkForge();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Templates;
|
using Avalonia.Controls.Templates;
|
||||||
|
|
||||||
|
|
@ -7,8 +8,6 @@ using InkForge.Desktop.ViewModels.Workspaces;
|
||||||
using InkForge.Desktop.Views.Documents;
|
using InkForge.Desktop.Views.Documents;
|
||||||
using InkForge.Desktop.Views.Workspaces;
|
using InkForge.Desktop.Views.Workspaces;
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop;
|
namespace InkForge.Desktop;
|
||||||
|
|
||||||
public class AppViewLocator : IDataTemplate
|
public class AppViewLocator : IDataTemplate
|
||||||
|
|
@ -19,6 +18,7 @@ public class AppViewLocator : IDataTemplate
|
||||||
return param switch
|
return param switch
|
||||||
#pragma warning restore CS8509 // The switch expression does not handle all possible values of its input type (it is not exhaustive).
|
#pragma warning restore CS8509 // The switch expression does not handle all possible values of its input type (it is not exhaustive).
|
||||||
{
|
{
|
||||||
|
NoteEditDocumentViewModel viewModel => _(new NoteEditDocument(), viewModel),
|
||||||
ViewModels.Tools.WorkspaceTool viewModel => _(new Views.Tools.WorkspaceTool(), viewModel),
|
ViewModels.Tools.WorkspaceTool viewModel => _(new Views.Tools.WorkspaceTool(), viewModel),
|
||||||
WelcomePageDocumentViewModel viewModel => _(new WelcomePageDocument(), viewModel),
|
WelcomePageDocumentViewModel viewModel => _(new WelcomePageDocument(), viewModel),
|
||||||
WorkspaceViewModel viewModel => _(new WorkspaceView(), viewModel),
|
WorkspaceViewModel viewModel => _(new WorkspaceView(), viewModel),
|
||||||
|
|
@ -26,9 +26,9 @@ public class AppViewLocator : IDataTemplate
|
||||||
|
|
||||||
static TView _<TView, TViewModel>(TView view, TViewModel viewModel)
|
static TView _<TView, TViewModel>(TView view, TViewModel viewModel)
|
||||||
where TViewModel : class
|
where TViewModel : class
|
||||||
where TView : IViewFor<TViewModel>
|
where TView : StyledElement
|
||||||
{
|
{
|
||||||
view.ViewModel = viewModel;
|
view.DataContext = viewModel;
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +36,7 @@ public class AppViewLocator : IDataTemplate
|
||||||
public bool Match(object? data)
|
public bool Match(object? data)
|
||||||
{
|
{
|
||||||
return data is
|
return data is
|
||||||
|
NoteEditDocumentViewModel or
|
||||||
RecentItemViewModel or
|
RecentItemViewModel or
|
||||||
ViewModels.Tools.WorkspaceTool or
|
ViewModels.Tools.WorkspaceTool or
|
||||||
WelcomePageDocumentViewModel or
|
WelcomePageDocumentViewModel or
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,21 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia.AvaloniaEdit" />
|
||||||
<PackageReference Include="Avalonia.Controls.DataGrid" />
|
<PackageReference Include="Avalonia.Controls.DataGrid" />
|
||||||
<PackageReference Include="Avalonia.Desktop" />
|
<PackageReference Include="Avalonia.Desktop" />
|
||||||
<PackageReference Include="Avalonia.Fonts.Inter" />
|
<PackageReference Include="Avalonia.Fonts.Inter" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" />
|
|
||||||
<PackageReference Include="Avalonia.Themes.Fluent" />
|
<PackageReference Include="Avalonia.Themes.Fluent" />
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||||
<PackageReference Include="Dock.Avalonia" />
|
<PackageReference Include="Dock.Avalonia" />
|
||||||
<PackageReference Include="Dock.Model.ReactiveUI" />
|
<PackageReference Include="Dock.Model.Mvvm" />
|
||||||
|
<PackageReference Include="DynamicData" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" />
|
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" />
|
<PackageReference Include="Microsoft.Extensions.Http" />
|
||||||
<PackageReference Include="SmartFormat" />
|
<PackageReference Include="SmartFormat" />
|
||||||
|
<PackageReference Include="Splat" />
|
||||||
<PackageReference Include="Splat.Microsoft.Extensions.DependencyInjection" />
|
<PackageReference Include="Splat.Microsoft.Extensions.DependencyInjection" />
|
||||||
<PackageReference Include="System.IO.Hashing" />
|
<PackageReference Include="System.IO.Hashing" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,67 @@
|
||||||
using Dock.Model.ReactiveUI;
|
using Avalonia;
|
||||||
|
|
||||||
using Dock.Model.Controls;
|
using Dock.Model.Controls;
|
||||||
using Dock.Model.Core;
|
using Dock.Model.Core;
|
||||||
using Dock.Model.ReactiveUI.Controls;
|
using Dock.Model.Mvvm;
|
||||||
using Dock.Avalonia.Controls;
|
using Dock.Model.Mvvm.Controls;
|
||||||
|
|
||||||
|
using DynamicData.Binding;
|
||||||
|
|
||||||
|
using InkForge.Desktop.Managers;
|
||||||
|
using InkForge.Desktop.Models;
|
||||||
|
using InkForge.Desktop.ViewModels.Documents;
|
||||||
|
using InkForge.Desktop.ViewModels.Tools;
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Avalonia;
|
|
||||||
using InkForge.Desktop.ViewModels;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop;
|
namespace InkForge.Desktop;
|
||||||
|
|
||||||
public class InkForgeFactory : Factory
|
public class InkForgeFactory : Factory
|
||||||
{
|
{
|
||||||
private readonly IDocumentDock _documentDock;
|
private readonly IDock _mainDock;
|
||||||
private readonly IRootDock _rootDock;
|
private readonly IRootDock _rootDock;
|
||||||
private readonly ViewModels.Tools.WorkspaceTool _workspaceTool;
|
private readonly WelcomePageDocumentViewModel _welcomePage;
|
||||||
|
private readonly WorkspaceTool _workspaceTool;
|
||||||
|
|
||||||
public InkForgeFactory()
|
public InkForgeFactory(WorkspaceManager workspace)
|
||||||
{
|
{
|
||||||
_rootDock = new RootDock
|
_rootDock = CreateRootDock();
|
||||||
{
|
_mainDock = CreateDockDock();
|
||||||
IsCollapsable = false,
|
_mainDock.IsCollapsable = false;
|
||||||
};
|
_mainDock.CanClose = false;
|
||||||
|
|
||||||
_documentDock = new DocumentDock
|
|
||||||
{
|
|
||||||
Id = "Documents",
|
|
||||||
Title = "Documents",
|
|
||||||
CanCreateDocument = false,
|
|
||||||
IsCollapsable = false,
|
|
||||||
Proportion = double.NaN,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
_welcomePage = CreateWelcomePageDocumentViewModel();
|
||||||
_workspaceTool = CreateWorkspaceTool();
|
_workspaceTool = CreateWorkspaceTool();
|
||||||
|
|
||||||
|
workspace.WhenValueChanged(m => m.Workspace).Subscribe(OnWorkspaceChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IRootDock CreateLayout()
|
public override IRootDock CreateLayout()
|
||||||
{
|
{
|
||||||
ProportionalDock workspaceLayout = new()
|
ToolDock toolDock = new()
|
||||||
{
|
{
|
||||||
Proportion = 0.3,
|
Alignment = Alignment.Left,
|
||||||
|
Proportion = 0.25,
|
||||||
VisibleDockables = [_workspaceTool],
|
VisibleDockables = [_workspaceTool],
|
||||||
};
|
};
|
||||||
|
|
||||||
ProportionalDock windowLayoutContent = new()
|
ProportionalDock windowLayoutContent = new()
|
||||||
{
|
{
|
||||||
Orientation = Orientation.Horizontal,
|
Orientation = Orientation.Horizontal,
|
||||||
IsCollapsable = false,
|
VisibleDockables = [toolDock, new ProportionalDockSplitter(), _mainDock]
|
||||||
VisibleDockables = [workspaceLayout, new ProportionalDockSplitter(), _documentDock]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RootDock windowLayout = new()
|
_rootDock.VisibleDockables = [windowLayoutContent];
|
||||||
{
|
_rootDock.DefaultDockable = windowLayoutContent;
|
||||||
Title = "Default",
|
|
||||||
IsCollapsable = false,
|
|
||||||
VisibleDockables = [windowLayoutContent],
|
|
||||||
ActiveDockable = windowLayoutContent,
|
|
||||||
};
|
|
||||||
|
|
||||||
_rootDock.VisibleDockables = [windowLayout];
|
|
||||||
_rootDock.ActiveDockable = windowLayout;
|
|
||||||
_rootDock.DefaultDockable = windowLayout;
|
|
||||||
|
|
||||||
return _rootDock;
|
return _rootDock;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitLayout(IDockable layout)
|
private static WelcomePageDocumentViewModel CreateWelcomePageDocumentViewModel()
|
||||||
{
|
{
|
||||||
DockableLocator = new Dictionary<string, Func<IDockable?>>
|
return ActivatorUtilities.CreateInstance<WelcomePageDocumentViewModel>(
|
||||||
{
|
Application.Current!.GetValue(App.ServiceProviderProperty)
|
||||||
["Root"] = () => _rootDock,
|
);
|
||||||
["Documents"] = () => _documentDock,
|
|
||||||
["Workspace"] = () => _workspaceTool,
|
|
||||||
};
|
|
||||||
|
|
||||||
HostWindowLocator = new Dictionary<string, Func<IHostWindow?>>
|
|
||||||
{
|
|
||||||
[nameof(IDockWindow)] = () => new HostWindow()
|
|
||||||
};
|
|
||||||
|
|
||||||
base.InitLayout(layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ViewModels.Tools.WorkspaceTool CreateWorkspaceTool()
|
private static ViewModels.Tools.WorkspaceTool CreateWorkspaceTool()
|
||||||
|
|
@ -87,4 +70,16 @@ public class InkForgeFactory : Factory
|
||||||
Application.Current!.GetValue(App.ServiceProviderProperty)
|
Application.Current!.GetValue(App.ServiceProviderProperty)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnWorkspaceChanged(Workspace? workspace)
|
||||||
|
{
|
||||||
|
IDockable dock = workspace switch
|
||||||
|
{
|
||||||
|
null => _welcomePage,
|
||||||
|
_ => workspace.Services.GetRequiredService<DocumentManager>().Dock,
|
||||||
|
};
|
||||||
|
|
||||||
|
AddDockable(_mainDock, dock);
|
||||||
|
CloseOtherDockables(dock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,38 @@
|
||||||
using Avalonia;
|
using AvaloniaEdit.Document;
|
||||||
|
|
||||||
using Dock.Model.Core;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
|
using Dock.Model.Controls;
|
||||||
|
|
||||||
using InkForge.Desktop.Models;
|
using InkForge.Desktop.Models;
|
||||||
using InkForge.Desktop.ViewModels.Documents;
|
using InkForge.Desktop.ViewModels.Documents;
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.Managers;
|
namespace InkForge.Desktop.Managers;
|
||||||
|
|
||||||
public class DocumentManager
|
public partial class DocumentManager
|
||||||
{
|
{
|
||||||
private readonly IDock _documents;
|
|
||||||
private readonly InkForgeFactory _factory;
|
private readonly InkForgeFactory _factory;
|
||||||
private readonly WelcomePageDocumentViewModel _welcomePage;
|
|
||||||
private readonly WorkspaceManager _workspaceManager;
|
|
||||||
|
|
||||||
public DocumentManager(WorkspaceManager workspaceManager, InkForgeFactory factory)
|
public IDocumentDock Dock { get; }
|
||||||
|
|
||||||
|
public DocumentManager(NoteStore noteStore, InkForgeFactory factory)
|
||||||
{
|
{
|
||||||
_workspaceManager = workspaceManager;
|
|
||||||
_factory = factory;
|
_factory = factory;
|
||||||
_documents = factory.GetDockable<IDock>("Documents")!;
|
Dock = factory.CreateDocumentDock();
|
||||||
_welcomePage = CreateWelcomePageDocumentViewModel();
|
Dock.IsCollapsable = false;
|
||||||
workspaceManager.WhenAnyValue(v => v.Workspace).Subscribe(OnWorkspaceChanged);
|
Dock.CanCreateDocument = true;
|
||||||
|
Dock.CreateDocument = CreateDocumentCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnWorkspaceChanged(Workspace? workspace)
|
[RelayCommand]
|
||||||
|
private void OnCreateDocument()
|
||||||
{
|
{
|
||||||
if (workspace is null)
|
NoteEditDocumentViewModel editViewModel = new(new()
|
||||||
{
|
{
|
||||||
_factory.AddDockable(_documents, _welcomePage);
|
Name = "Untitled Note",
|
||||||
}
|
}, new());
|
||||||
else
|
_factory.AddDockable(Dock, editViewModel);
|
||||||
{
|
_factory.SetActiveDockable(editViewModel);
|
||||||
_factory.RemoveDockable(_welcomePage, false);
|
_factory.SetFocusedDockable(Dock, editViewModel);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static WelcomePageDocumentViewModel CreateWelcomePageDocumentViewModel()
|
|
||||||
{
|
|
||||||
return ActivatorUtilities.CreateInstance<WelcomePageDocumentViewModel>(
|
|
||||||
Application.Current!.GetValue(App.ServiceProviderProperty)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
using Avalonia;
|
||||||
|
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
using InkForge.Data;
|
using InkForge.Data;
|
||||||
using InkForge.Desktop.Data.Options;
|
using InkForge.Desktop.Data.Options;
|
||||||
using InkForge.Desktop.Models;
|
using InkForge.Desktop.Models;
|
||||||
|
|
@ -5,24 +9,16 @@ using InkForge.Desktop.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.Managers;
|
namespace InkForge.Desktop.Managers;
|
||||||
|
|
||||||
public class WorkspaceManager(IServiceProvider serviceProvider) : ReactiveObject
|
public partial class WorkspaceManager(IServiceProvider serviceProvider) : ObservableObject
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider = serviceProvider;
|
private readonly IServiceProvider _serviceProvider = serviceProvider;
|
||||||
private Workspace? _workspace;
|
[ObservableProperty] private Workspace? _workspace;
|
||||||
|
|
||||||
public Workspace? Workspace
|
|
||||||
{
|
|
||||||
get => _workspace;
|
|
||||||
private set => this.RaiseAndSetIfChanged(ref _workspace, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueTask CloseWorkspace()
|
public ValueTask CloseWorkspace()
|
||||||
{
|
{
|
||||||
_workspace?.Dispose();
|
Workspace?.Dispose();
|
||||||
Workspace = null;
|
Workspace = null;
|
||||||
return ValueTask.CompletedTask;
|
return ValueTask.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +62,7 @@ public class WorkspaceManager(IServiceProvider serviceProvider) : ReactiveObject
|
||||||
var db = dbContext.Database;
|
var db = dbContext.Database;
|
||||||
if ((await db.GetPendingMigrationsAsync().ConfigureAwait(false)).Any())
|
if ((await db.GetPendingMigrationsAsync().ConfigureAwait(false)).Any())
|
||||||
{
|
{
|
||||||
if (file.Exists)
|
if ((await db.GetAppliedMigrationsAsync().ConfigureAwait(false)).Any())
|
||||||
{
|
{
|
||||||
file.CopyTo(Path.ChangeExtension(file.FullName, $"{DateTime.Now:s}{file.Extension}"));
|
file.CopyTo(Path.ChangeExtension(file.FullName, $"{DateTime.Now:s}{file.Extension}"));
|
||||||
}
|
}
|
||||||
|
|
@ -74,6 +70,8 @@ public class WorkspaceManager(IServiceProvider serviceProvider) : ReactiveObject
|
||||||
await db.MigrateAsync().ConfigureAwait(false);
|
await db.MigrateAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await serviceProvider.GetRequiredService<NoteStore>().Load().ConfigureAwait(false);
|
||||||
|
|
||||||
scope = null;
|
scope = null;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ public static class InkForgeServiceCollections
|
||||||
|
|
||||||
// Singletons
|
// Singletons
|
||||||
// - Concrete
|
// - Concrete
|
||||||
services.AddSingleton<DocumentManager>();
|
|
||||||
services.AddSingleton<InkForgeFactory>();
|
services.AddSingleton<InkForgeFactory>();
|
||||||
services.AddSingleton<WorkspaceManager>();
|
services.AddSingleton<WorkspaceManager>();
|
||||||
|
|
||||||
|
|
@ -33,6 +32,7 @@ public static class InkForgeServiceCollections
|
||||||
|
|
||||||
// Scoped
|
// Scoped
|
||||||
// - Concrete
|
// - Concrete
|
||||||
|
services.AddScoped<DocumentManager>();
|
||||||
services.AddScoped<LocalWorkspaceOptions>();
|
services.AddScoped<LocalWorkspaceOptions>();
|
||||||
services.AddScoped<NoteStore>();
|
services.AddScoped<NoteStore>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,12 @@
|
||||||
using System.Reactive.Linq;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.Reactive.Subjects;
|
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.Models;
|
namespace InkForge.Desktop.Models;
|
||||||
|
|
||||||
public class Note : ReactiveObject
|
public partial class Note : ObservableObject
|
||||||
{
|
{
|
||||||
private readonly ObservableAsPropertyHelper<Note?> _parent;
|
[ObservableProperty] private DateTimeOffset _createdTime;
|
||||||
private readonly BehaviorSubject<int?> _parentId = new(default);
|
[ObservableProperty] private int _id;
|
||||||
private DateTimeOffset _createdTime;
|
[ObservableProperty] private string _name = default!;
|
||||||
private int _id;
|
[ObservableProperty] private int? _parentId;
|
||||||
private string _name = default!;
|
[ObservableProperty] private DateTimeOffset _updatedTime;
|
||||||
private DateTimeOffset _updatedTime;
|
|
||||||
|
|
||||||
public DateTimeOffset CreatedTime
|
|
||||||
{
|
|
||||||
get => _createdTime;
|
|
||||||
set => this.RaiseAndSetIfChanged(ref _createdTime, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Id
|
|
||||||
{
|
|
||||||
get => _id;
|
|
||||||
set => this.RaiseAndSetIfChanged(ref _id, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get => _name;
|
|
||||||
set => this.RaiseAndSetIfChanged(ref _name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset UpdatedTime
|
|
||||||
{
|
|
||||||
get => _updatedTime;
|
|
||||||
set => this.RaiseAndSetIfChanged(ref _updatedTime, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Note? Parent
|
|
||||||
{
|
|
||||||
get => _parent.Value;
|
|
||||||
set => ParentId = value?.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int? ParentId
|
|
||||||
{
|
|
||||||
get => _parentId.Value;
|
|
||||||
set => _parentId.OnNext(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Note(NoteStore noteStore)
|
|
||||||
{
|
|
||||||
_parent = _parentId.Select(id => id switch
|
|
||||||
{
|
|
||||||
{ } => noteStore.Watch((int)id),
|
|
||||||
_ => Observable.Empty<Note?>(),
|
|
||||||
}).Switch(null).ToProperty(this, nameof(Parent), deferSubscription: true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
using System.Collections.ObjectModel;
|
using Avalonia.Collections;
|
||||||
using System.Reactive.Linq;
|
|
||||||
|
|
||||||
using DynamicData;
|
|
||||||
|
|
||||||
using InkForge.Data;
|
using InkForge.Data;
|
||||||
|
|
||||||
|
|
@ -9,51 +6,46 @@ using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace InkForge.Desktop.Models;
|
namespace InkForge.Desktop.Models;
|
||||||
|
|
||||||
public class NoteStore
|
public class NoteStore(IDbContextFactory<NoteDbContext> dbContextFactory)
|
||||||
{
|
{
|
||||||
private readonly IDbContextFactory<NoteDbContext> _dbContextFactory;
|
public AvaloniaDictionary<int, Note> Notes { get; } = [];
|
||||||
private readonly SourceCache<Note, int> _notesCache = new(m => m.Id);
|
|
||||||
|
|
||||||
public ReadOnlyObservableCollection<Note> Notes { get; }
|
public async ValueTask Load()
|
||||||
|
|
||||||
public NoteStore(IDbContextFactory<NoteDbContext> dbContextFactory)
|
|
||||||
{
|
{
|
||||||
_dbContextFactory = dbContextFactory;
|
await using var dbContext = await dbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
|
||||||
|
Notes.Clear();
|
||||||
|
await foreach (var note in dbContext.Notes.AsAsyncEnumerable().ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
Notes.Add(note.Id, Map(note));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddNote(Note note)
|
public void AddNote(Note note)
|
||||||
{
|
{
|
||||||
using var dbContext = _dbContextFactory.CreateDbContext();
|
using var dbContext = dbContextFactory.CreateDbContext();
|
||||||
var entity = ToEntity(note);
|
var entity = Map(note);
|
||||||
var entry = dbContext.Notes.Add(entity);
|
var entry = dbContext.Notes.Add(entity);
|
||||||
|
|
||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Note CreateNote() => new(this);
|
|
||||||
|
|
||||||
public Note? GetById(int id)
|
public Note? GetById(int id)
|
||||||
{
|
{
|
||||||
if (((Note?)_notesCache.Lookup(id)) is not Note note)
|
if (!Notes.TryGetValue(id, out var note))
|
||||||
{
|
{
|
||||||
using var dbContext = _dbContextFactory.CreateDbContext();
|
using var dbContext = dbContextFactory.CreateDbContext();
|
||||||
if (dbContext.Notes.Find(id) is not { } dbNote)
|
if (dbContext.Notes.Find(id) is not { } dbNote)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
note = ToNote(dbNote);
|
Notes.Add(id, note = Map(dbNote));
|
||||||
}
|
}
|
||||||
|
|
||||||
return note;
|
return note;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IObservable<Note?> Watch(int id)
|
private NoteEntity Map(Note note)
|
||||||
{
|
|
||||||
return _notesCache.WatchValue(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private NoteEntity ToEntity(Note note)
|
|
||||||
{
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
|
|
@ -64,25 +56,26 @@ public class NoteStore
|
||||||
Created = note.CreatedTime,
|
Created = note.CreatedTime,
|
||||||
Updated = note.UpdatedTime,
|
Updated = note.UpdatedTime,
|
||||||
},
|
},
|
||||||
Parent = note.Parent switch
|
Parent = note.ParentId switch
|
||||||
{
|
{
|
||||||
{ Id: { } parentId } => new()
|
{ } parentId => new()
|
||||||
{
|
{
|
||||||
Id = parentId
|
Id = parentId
|
||||||
},
|
},
|
||||||
_ => null,
|
_ => null
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Note ToNote(NoteEntity entity)
|
private Note Map(NoteEntity entity)
|
||||||
{
|
{
|
||||||
var note = CreateNote();
|
return new()
|
||||||
note.Id = entity.Id;
|
{
|
||||||
note.Name = entity.Value.Name;
|
Id = entity.Id,
|
||||||
note.CreatedTime = entity.Value.Created;
|
Name = entity.Value.Name,
|
||||||
note.UpdatedTime = entity.Value.Updated;
|
CreatedTime = entity.Value.Created,
|
||||||
note.ParentId = entity.Parent?.Id;
|
UpdatedTime = entity.Value.Updated,
|
||||||
return note;
|
ParentId = entity.Parent?.Id
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
131
app/InkForge.Desktop/Models/TextDocumentStore.cs
Normal file
131
app/InkForge.Desktop/Models/TextDocumentStore.cs
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Avalonia.Collections;
|
||||||
|
|
||||||
|
using AvaloniaEdit.Document;
|
||||||
|
|
||||||
|
using InkForge.Data;
|
||||||
|
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace InkForge.Desktop.Models;
|
||||||
|
|
||||||
|
public class TextDocumentStore(IDbContextFactory<NoteDbContext> dbContextFactory)
|
||||||
|
{
|
||||||
|
private readonly AvaloniaDictionary<int, TextDocument> _cache = [];
|
||||||
|
|
||||||
|
public void Close(int id)
|
||||||
|
{
|
||||||
|
if (_cache.Remove(id, out var document))
|
||||||
|
{
|
||||||
|
document.Remove(0, document.TextLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextDocument Get(int id)
|
||||||
|
{
|
||||||
|
if (!_cache.TryGetValue(id, out var document))
|
||||||
|
{
|
||||||
|
using var dbContext = dbContextFactory.CreateDbContext();
|
||||||
|
var connection = dbContext.Database.GetDbConnection();
|
||||||
|
using var command = connection.CreateCommand();
|
||||||
|
command.CommandText = $"SELECT rowid FROM Blobs WHERE Id={id}";
|
||||||
|
using var commandReader = command.ExecuteReader();
|
||||||
|
document = new();
|
||||||
|
if (commandReader.Read())
|
||||||
|
{
|
||||||
|
using SqliteBlob stream = new((SqliteConnection)connection, "Blob", "Value", commandReader.GetInt64(0), true);
|
||||||
|
CopyDocumentContent(stream, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
_cache.Add(id, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
|
|
||||||
|
static void CopyDocumentContent(Stream stream, TextDocument document)
|
||||||
|
{
|
||||||
|
DocumentTextWriter writer = new(document, 0);
|
||||||
|
StreamReader reader = new(stream, Encoding.UTF8);
|
||||||
|
Span<char> buffer = stackalloc char[128];
|
||||||
|
while (!reader.EndOfStream)
|
||||||
|
{
|
||||||
|
var read = reader.Read(buffer);
|
||||||
|
writer.Write(buffer[..read]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? Save(int? id, TextDocument textDocument)
|
||||||
|
{
|
||||||
|
var state = textDocument.CreateSnapshot();
|
||||||
|
var bytes = TextBytes(state);
|
||||||
|
|
||||||
|
using var dbContext = dbContextFactory.CreateDbContext();
|
||||||
|
var connection = dbContext.Database.GetDbConnection();
|
||||||
|
using var transaction = dbContext.Database.BeginTransaction();
|
||||||
|
using var command = connection.CreateCommand();
|
||||||
|
command.CommandText = id switch
|
||||||
|
{
|
||||||
|
null => $"INSERT INTO Blobs(Value) VALUES(zeroblob({bytes})) RETURNING (Id, rowid)",
|
||||||
|
_ => $"UPDATE Blobs SET Value=zeroblob({bytes}) WHERE Id={id} RETURNING (Id, rowid)"
|
||||||
|
};
|
||||||
|
using var commandReader = command.ExecuteReader();
|
||||||
|
if (!commandReader.Read())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = commandReader.GetInt32(0);
|
||||||
|
using (SqliteBlob stream = new((SqliteConnection)connection, "Blobs", "Value", commandReader.GetInt64(1)))
|
||||||
|
{
|
||||||
|
using StreamWriter writer = new(stream, Encoding.UTF8);
|
||||||
|
state.WriteTextTo(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
_cache.TryAdd((int)id, textDocument);
|
||||||
|
return id;
|
||||||
|
|
||||||
|
static int TextBytes(ITextSource text)
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
Span<byte> byteBuffer = stackalloc byte[128];
|
||||||
|
using var reader = text.CreateReader();
|
||||||
|
ArrayBufferWriter<char> buffer = new();
|
||||||
|
var encoder = Encoding.UTF8.GetEncoder();
|
||||||
|
while (reader.Peek() != -1)
|
||||||
|
{
|
||||||
|
var memory = buffer.GetMemory();
|
||||||
|
buffer.Advance(reader.Read(memory.Span));
|
||||||
|
ReadOnlySpan<char> chars = buffer.WrittenSpan;
|
||||||
|
|
||||||
|
convert:
|
||||||
|
encoder.Convert(buffer.WrittenSpan, byteBuffer, false, out var charsUsed, out var bytesUsed, out _);
|
||||||
|
chars = chars[charsUsed..];
|
||||||
|
if (bytesUsed > 0)
|
||||||
|
{
|
||||||
|
length += bytesUsed;
|
||||||
|
goto convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<char> remaining = [];
|
||||||
|
if (!chars.IsEmpty)
|
||||||
|
{
|
||||||
|
remaining = buffer.GetSpan(chars.Length);
|
||||||
|
chars.CopyTo(remaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.Clear();
|
||||||
|
if (!remaining.IsEmpty)
|
||||||
|
{
|
||||||
|
buffer.Write(remaining);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,21 +4,16 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace InkForge.Desktop.Models;
|
namespace InkForge.Desktop.Models;
|
||||||
|
|
||||||
public sealed class Workspace : IDisposable
|
public sealed class Workspace(IServiceScope scope) : IDisposable
|
||||||
{
|
{
|
||||||
private bool _disposedValue;
|
private bool _disposedValue;
|
||||||
private IServiceScope? _scope;
|
private IServiceScope? _scope = scope;
|
||||||
|
|
||||||
public string Name { get; set; } = default!;
|
public string Name { get; set; } = default!;
|
||||||
|
|
||||||
public LocalWorkspaceOptions Options { get; set; } = default!;
|
public LocalWorkspaceOptions Options { get; set; } = default!;
|
||||||
|
|
||||||
public IServiceProvider Services => _scope!.ServiceProvider;
|
public IServiceProvider Services { get; } = scope.ServiceProvider;
|
||||||
|
|
||||||
public Workspace(IServiceScope scope)
|
|
||||||
{
|
|
||||||
_scope = scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
@ -33,14 +28,4 @@ public sealed class Workspace : IDisposable
|
||||||
_disposedValue = true;
|
_disposedValue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private async Task LoadNotes()
|
|
||||||
// {
|
|
||||||
// await using var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
|
|
||||||
// await foreach (var asdf in dbContext.Notes.AsAsyncEnumerable().ConfigureAwait(false))
|
|
||||||
// {
|
|
||||||
|
|
||||||
// }
|
|
||||||
// _ = (await dbContext.Notes.ToListAsync().ConfigureAwait(false));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.ReactiveUI;
|
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
|
||||||
using InkForge.Desktop;
|
using InkForge.Desktop;
|
||||||
|
|
@ -20,7 +19,6 @@ static class Program
|
||||||
public static AppBuilder BuildAvaloniaApp()
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
=> AppBuilder.Configure<App>()
|
=> AppBuilder.Configure<App>()
|
||||||
.UsePlatformDetect()
|
.UsePlatformDetect()
|
||||||
.UseReactiveUI()
|
|
||||||
.WithInterFont()
|
.WithInterFont()
|
||||||
.LogToTrace();
|
.LogToTrace();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
|
@ -52,7 +53,7 @@ public class TopLevels
|
||||||
// Register any new context
|
// Register any new context
|
||||||
if (e.NewValue != null)
|
if (e.NewValue != null)
|
||||||
{
|
{
|
||||||
RegistrationMapper.Add(e.NewValue, sender);
|
CollectionsMarshal.GetValueRefOrAddDefault(RegistrationMapper, e.NewValue, out _) = sender;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
|
||||||
|
using AvaloniaEdit.Document;
|
||||||
|
|
||||||
|
using Dock.Model.Mvvm.Controls;
|
||||||
|
|
||||||
|
using DynamicData.Binding;
|
||||||
|
|
||||||
|
using InkForge.Desktop.Models;
|
||||||
|
|
||||||
|
namespace InkForge.Desktop.ViewModels.Documents;
|
||||||
|
|
||||||
|
public class NoteEditDocumentViewModel : Document
|
||||||
|
{
|
||||||
|
public Note Note { get; }
|
||||||
|
|
||||||
|
public TextDocument Document { get; }
|
||||||
|
|
||||||
|
public NoteEditDocumentViewModel(Note note, TextDocument textDocument)
|
||||||
|
{
|
||||||
|
Note = note;
|
||||||
|
Document = textDocument;
|
||||||
|
|
||||||
|
Observable.CombineLatest(
|
||||||
|
this.WhenValueChanged(v => v.Note.Name),
|
||||||
|
this.WhenValueChanged(v => v.Document.UndoStack.IsOriginalFile),
|
||||||
|
(name, original) => original ? name : $"{name} *"
|
||||||
|
).Subscribe(title => Title = title!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,33 +2,28 @@ using System.Reactive;
|
||||||
|
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
|
|
||||||
using Dock.Model.ReactiveUI.Controls;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
|
||||||
|
using Dock.Model.Mvvm.Controls;
|
||||||
|
|
||||||
using InkForge.Desktop.Managers;
|
using InkForge.Desktop.Managers;
|
||||||
using InkForge.Desktop.Services;
|
using InkForge.Desktop.Services;
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.ViewModels.Documents;
|
namespace InkForge.Desktop.ViewModels.Documents;
|
||||||
|
|
||||||
public class WelcomePageDocumentViewModel : Document
|
public partial class WelcomePageDocumentViewModel : Document
|
||||||
{
|
{
|
||||||
private readonly WorkspaceManager _workspaceController;
|
private readonly WorkspaceManager _workspaceController;
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> CreateNew { get; }
|
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> OpenNew { get; }
|
|
||||||
|
|
||||||
public WelcomePageDocumentViewModel(WorkspaceManager workspaceController)
|
public WelcomePageDocumentViewModel(WorkspaceManager workspaceController)
|
||||||
{
|
{
|
||||||
CanClose = false;
|
|
||||||
Title = "Welcome";
|
Title = "Welcome";
|
||||||
|
|
||||||
_workspaceController = workspaceController;
|
_workspaceController = workspaceController;
|
||||||
CreateNew = ReactiveCommand.CreateFromTask(OnCreateNew);
|
|
||||||
OpenNew = ReactiveCommand.CreateFromTask(OnOpenNew);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
private async Task OnCreateNew()
|
private async Task OnCreateNew()
|
||||||
{
|
{
|
||||||
var storageProvider = this.GetStorageProvider()!;
|
var storageProvider = this.GetStorageProvider()!;
|
||||||
|
|
@ -56,6 +51,7 @@ public class WelcomePageDocumentViewModel : Document
|
||||||
await _workspaceController.OpenWorkspace(filePath, true);
|
await _workspaceController.OpenWorkspace(filePath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
private async Task OnOpenNew()
|
private async Task OnOpenNew()
|
||||||
{
|
{
|
||||||
var storageProvider = this.GetStorageProvider()!;
|
var storageProvider = this.GetStorageProvider()!;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
using Dock.Model.Core;
|
|
||||||
using Dock.Model.ReactiveUI.Controls;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.ViewModels;
|
|
||||||
|
|
||||||
public class InkForgeDocumentDock : DocumentDock, IDock
|
|
||||||
{
|
|
||||||
bool IDock.IsEmpty
|
|
||||||
{
|
|
||||||
get => false;
|
|
||||||
set { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +1,16 @@
|
||||||
using Avalonia;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
using Dock.Model.Core;
|
using Dock.Model.Core;
|
||||||
|
|
||||||
using InkForge.Desktop.Managers;
|
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.ViewModels;
|
namespace InkForge.Desktop.ViewModels;
|
||||||
|
|
||||||
public class MainViewModel : ReactiveObject
|
public class MainViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
private readonly DocumentManager _documentManager;
|
|
||||||
public IDock Layout { get; }
|
public IDock Layout { get; }
|
||||||
|
|
||||||
public MainViewModel(InkForgeFactory factory)
|
public MainViewModel(InkForgeFactory factory)
|
||||||
{
|
{
|
||||||
Layout = factory.CreateLayout();
|
Layout = factory.CreateLayout();
|
||||||
factory.InitLayout(Layout);
|
factory.InitLayout(Layout);
|
||||||
|
|
||||||
_documentManager = CreateDocumentManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DocumentManager CreateDocumentManager()
|
|
||||||
{
|
|
||||||
return ActivatorUtilities.CreateInstance<DocumentManager>(
|
|
||||||
Application.Current!.GetValue(App.ServiceProviderProperty)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
using ReactiveUI;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace InkForge.Desktop.ViewModels;
|
namespace InkForge.Desktop.ViewModels;
|
||||||
|
|
||||||
public record class RecentItemViewModel(
|
public partial class RecentItemViewModel(
|
||||||
DateTimeOffset Created,
|
DateTimeOffset created,
|
||||||
string Name,
|
string name,
|
||||||
DateTimeOffset LastUsed
|
DateTimeOffset lastUsed
|
||||||
) : ReactiveRecord;
|
) : ObservableObject
|
||||||
|
{
|
||||||
|
[ObservableProperty] private DateTimeOffset _created = created;
|
||||||
|
[ObservableProperty] private string _name = name;
|
||||||
|
[ObservableProperty] private DateTimeOffset _lastUsed = lastUsed;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,40 @@
|
||||||
using Dock.Model.ReactiveUI.Controls;
|
using System.Reactive.Linq;
|
||||||
|
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
using Dock.Model.Mvvm.Controls;
|
||||||
|
|
||||||
|
using DynamicData.Binding;
|
||||||
|
|
||||||
using InkForge.Desktop.Managers;
|
using InkForge.Desktop.Managers;
|
||||||
|
using InkForge.Desktop.Models;
|
||||||
using InkForge.Desktop.ViewModels.Workspaces;
|
using InkForge.Desktop.ViewModels.Workspaces;
|
||||||
|
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.ViewModels.Tools;
|
namespace InkForge.Desktop.ViewModels.Tools;
|
||||||
|
|
||||||
public class WorkspaceTool : Tool
|
public partial class WorkspaceTool : Tool
|
||||||
{
|
{
|
||||||
private WorkspaceViewModel? _workspace;
|
private readonly IWorkspaceViewModelFactory _workspaceViewModelFactory;
|
||||||
|
[ObservableProperty] private WorkspaceViewModel? _workspace;
|
||||||
public WorkspaceViewModel? Workspace
|
|
||||||
{
|
|
||||||
get => _workspace;
|
|
||||||
private set => this.RaiseAndSetIfChanged(ref _workspace, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WorkspaceTool(WorkspaceManager workspaceManager, IWorkspaceViewModelFactory workspaceViewModelFactory)
|
public WorkspaceTool(WorkspaceManager workspaceManager, IWorkspaceViewModelFactory workspaceViewModelFactory)
|
||||||
{
|
{
|
||||||
Title = "Workspace";
|
_workspaceViewModelFactory = workspaceViewModelFactory;
|
||||||
CanClose = false;
|
|
||||||
|
|
||||||
workspaceManager.WhenAnyValue(v => v.Workspace,
|
Title = "Explorer";
|
||||||
v => v switch
|
CanClose = false;
|
||||||
{
|
CanFloat = false;
|
||||||
{ } => workspaceViewModelFactory.Create(v),
|
CanPin = false;
|
||||||
_ => null
|
|
||||||
}).BindTo(this, v => v.Workspace);
|
workspaceManager.WhenValueChanged(v => v.Workspace).Subscribe(OnWorkspaceManagerWorkspaceChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnWorkspaceManagerWorkspaceChanged(Workspace? workspace)
|
||||||
|
{
|
||||||
|
Workspace = workspace switch
|
||||||
|
{
|
||||||
|
{ } v => _workspaceViewModelFactory.Create(v),
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
using Avalonia;
|
||||||
|
|
||||||
|
using DynamicData;
|
||||||
|
|
||||||
using InkForge.Desktop.Models;
|
using InkForge.Desktop.Models;
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -6,30 +12,24 @@ namespace InkForge.Desktop.ViewModels.Workspaces
|
||||||
{
|
{
|
||||||
public class WorkspaceViewModel
|
public class WorkspaceViewModel
|
||||||
{
|
{
|
||||||
|
private readonly Workspace _workspace;
|
||||||
private readonly NoteStore _noteStore;
|
private readonly NoteStore _noteStore;
|
||||||
// private readonly ObservableAsPropertyHelper<string> _workspaceNameProperty;
|
private readonly ReadOnlyObservableCollection<Node<Note, int>> _notes;
|
||||||
|
|
||||||
// public string WorkspaceName => _workspaceNameProperty.Value;
|
public string Name => _workspace.Name;
|
||||||
|
|
||||||
// public ReactiveCommand<Unit, Unit> AddDocument { get; }
|
public ReadOnlyObservableCollection<Node<Note, int>> Notes => _notes;
|
||||||
|
|
||||||
public WorkspaceViewModel(NoteStore noteStore)
|
public WorkspaceViewModel(Workspace workspace, NoteStore noteStore)
|
||||||
{
|
{
|
||||||
|
_workspace = workspace;
|
||||||
_noteStore = noteStore;
|
_noteStore = noteStore;
|
||||||
|
noteStore.Notes
|
||||||
|
.AsObservableChangeSet(m => m.Key)
|
||||||
|
.Transform(m => m.Value, true)
|
||||||
|
.TransformToTree(m => m.Id)
|
||||||
|
.Bind(out _notes).Subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public WorkspacesViewModel(Workspace workspace)
|
|
||||||
// {
|
|
||||||
// _workspace = workspace;
|
|
||||||
// _workspaceNameProperty = this.WhenAnyValue(v => v._workspace.Name).ToProperty(this, nameof(WorkspaceName));
|
|
||||||
|
|
||||||
// AddDocument = ReactiveCommand.Create(OnAddDocument);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private void OnAddDocument()
|
|
||||||
// {
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IWorkspaceViewModelFactory
|
public interface IWorkspaceViewModelFactory
|
||||||
|
|
@ -39,14 +39,14 @@ namespace InkForge.Desktop.ViewModels.Workspaces
|
||||||
|
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
internal class WorkspaceViewModelFactory(IServiceProvider services) : IWorkspaceViewModelFactory
|
internal class WorkspaceViewModelFactory : IWorkspaceViewModelFactory
|
||||||
{
|
{
|
||||||
private static ObjectFactory<WorkspaceViewModel>? s_workspaceViewModelFactory;
|
private static ObjectFactory<WorkspaceViewModel>? s_workspaceViewModelFactory;
|
||||||
|
|
||||||
public WorkspaceViewModel Create(Workspace workspace)
|
public static WorkspaceViewModel Create(Workspace workspace)
|
||||||
{
|
{
|
||||||
s_workspaceViewModelFactory ??= ActivatorUtilities.CreateFactory<WorkspaceViewModel>([typeof(Workspace)]);
|
s_workspaceViewModelFactory ??= ActivatorUtilities.CreateFactory<WorkspaceViewModel>([typeof(Workspace)]);
|
||||||
return s_workspaceViewModelFactory(services, [workspace]);
|
return s_workspaceViewModelFactory(workspace.Services, [workspace]);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkspaceViewModel IWorkspaceViewModelFactory.Create(Workspace workspace) => Create(workspace);
|
WorkspaceViewModel IWorkspaceViewModelFactory.Create(Workspace workspace) => Create(workspace);
|
||||||
|
|
|
||||||
15
app/InkForge.Desktop/Views/Documents/NoteEditDocument.axaml
Normal file
15
app/InkForge.Desktop/Views/Documents/NoteEditDocument.axaml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:vm="using:InkForge.Desktop.ViewModels.Documents"
|
||||||
|
xmlns:avaloniaedit="https://github.com/avaloniaui/avaloniaedit"
|
||||||
|
xmlns:inkforge="app:InkForge"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignWidth="800"
|
||||||
|
d:DesignHeight="450"
|
||||||
|
x:Class="InkForge.Desktop.Views.Documents.NoteEditDocument"
|
||||||
|
x:DataType="vm:NoteEditDocumentViewModel"
|
||||||
|
inkforge:TopLevels.Register="{CompiledBinding}">
|
||||||
|
<avaloniaedit:TextEditor Document="{CompiledBinding Document}" />
|
||||||
|
</UserControl>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace InkForge.Desktop.Views.Documents;
|
||||||
|
|
||||||
|
public partial class NoteEditDocument : UserControl
|
||||||
|
{
|
||||||
|
public NoteEditDocument()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,11 +28,11 @@
|
||||||
|
|
||||||
<Menu Grid.Row="2">
|
<Menu Grid.Row="2">
|
||||||
<MenuItem Header="Create New"
|
<MenuItem Header="Create New"
|
||||||
Command="{CompiledBinding CreateNew}" />
|
Command="{CompiledBinding CreateNewCommand}" />
|
||||||
<MenuItem Header="Open"
|
<MenuItem Header="Open"
|
||||||
IsEnabled="False" />
|
IsEnabled="False" />
|
||||||
<MenuItem Header="Open File"
|
<MenuItem Header="Open File"
|
||||||
Command="{CompiledBinding OpenNew}" />
|
Command="{CompiledBinding OpenNewCommand}" />
|
||||||
</Menu>
|
</Menu>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.Controls;
|
||||||
|
|
||||||
using InkForge.Desktop.ViewModels.Documents;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.Views.Documents;
|
namespace InkForge.Desktop.Views.Documents;
|
||||||
|
|
||||||
public partial class WelcomePageDocument : ReactiveUserControl<WelcomePageDocumentViewModel>
|
public partial class WelcomePageDocument : UserControl
|
||||||
{
|
{
|
||||||
public WelcomePageDocument()
|
public WelcomePageDocument()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.Controls;
|
||||||
|
|
||||||
using InkForge.Desktop.ViewModels;
|
using InkForge.Desktop.ViewModels;
|
||||||
|
|
||||||
|
|
@ -7,12 +7,12 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace InkForge.Desktop.Views;
|
namespace InkForge.Desktop.Views;
|
||||||
|
|
||||||
public partial class MainWindow : ReactiveWindow<MainViewModel>
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
ViewModel = CreateViewModel();
|
DataContext = CreateViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MainViewModel CreateViewModel()
|
private static MainViewModel CreateViewModel()
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.Controls;
|
||||||
|
|
||||||
namespace InkForge.Desktop.Views.Tools;
|
namespace InkForge.Desktop.Views.Tools;
|
||||||
|
|
||||||
public partial class WorkspaceTool : ReactiveUserControl<ViewModels.Tools.WorkspaceTool>
|
public partial class WorkspaceTool : UserControl
|
||||||
{
|
{
|
||||||
public WorkspaceTool()
|
public WorkspaceTool()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
<Grid ColumnDefinitions="*, Auto"
|
<Grid ColumnDefinitions="*, Auto"
|
||||||
RowDefinitions="Auto, *">
|
RowDefinitions="Auto, *">
|
||||||
<TextBlock Grid.Column="0"
|
<TextBlock Text="{CompiledBinding Name}"
|
||||||
|
Grid.Column="0"
|
||||||
Grid.Row="0" />
|
Grid.Row="0" />
|
||||||
|
|
||||||
<StackPanel Classes="WorkspaceToolbar"
|
<StackPanel Classes="WorkspaceToolbar"
|
||||||
|
|
@ -29,22 +30,6 @@
|
||||||
<Button>
|
<Button>
|
||||||
<inkforge:FluentSymbolIcon Symbol="subtract_square_multiple" />
|
<inkforge:FluentSymbolIcon Symbol="subtract_square_multiple" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<!-- <StackPanel.Styles>
|
|
||||||
<Style Selector="#ToolBar > :is(TemplatedControl)">
|
|
||||||
<Setter Property="Background"
|
|
||||||
Value="Transparent" />
|
|
||||||
<Setter Property="Padding"
|
|
||||||
Value="1" />
|
|
||||||
<Setter Property="VerticalAlignment"
|
|
||||||
Value="Center" />
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<Style Selector="#FilesView:not(:pointerover) StackPanel">
|
|
||||||
<Setter Property="IsVisible"
|
|
||||||
Value="False" />
|
|
||||||
</Style>
|
|
||||||
</StackPanel.Styles> -->
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TreeView Grid.ColumnSpan="2"
|
<TreeView Grid.ColumnSpan="2"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.Controls;
|
||||||
|
|
||||||
using InkForge.Desktop.ViewModels.Workspaces;
|
|
||||||
|
|
||||||
namespace InkForge.Desktop.Views.Workspaces;
|
namespace InkForge.Desktop.Views.Workspaces;
|
||||||
|
|
||||||
public partial class WorkspaceView : ReactiveUserControl<WorkspaceViewModel>
|
public partial class WorkspaceView : UserControl
|
||||||
{
|
{
|
||||||
public WorkspaceView()
|
public WorkspaceView()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
namespace InkForge.Data;
|
namespace InkForge.Data;
|
||||||
|
|
||||||
public class Blob : Entity<byte[], string>;
|
public class Blob : Entity<byte[], int>;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ public class NoteDbContext(
|
||||||
{
|
{
|
||||||
options.HasKey(m => m.Id);
|
options.HasKey(m => m.Id);
|
||||||
|
|
||||||
options.OwnsOne(m => m.Value);
|
options.OwnsOne(m => m.Value, m =>
|
||||||
|
{
|
||||||
|
m.HasOne<Blob>().WithOne().HasForeignKey<Note>(m => m.ContentId).IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
options.HasOne(m => m.Parent);
|
options.HasOne(m => m.Parent);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ namespace InkForge.Data
|
||||||
{
|
{
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = default!;
|
public int ContentId { get; set; }
|
||||||
|
|
||||||
public DateTimeOffset Updated { get; set; }
|
|
||||||
|
|
||||||
public DateTimeOffset? Deleted { get; set; }
|
public DateTimeOffset? Deleted { get; set; }
|
||||||
|
|
||||||
public Blob Content { get; set; } = default!;
|
public string Name { get; set; } = default!;
|
||||||
|
|
||||||
|
public DateTimeOffset Updated { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NoteEntity : Entity<NoteEntity, Note, int>;
|
public class NoteEntity : Entity<NoteEntity, Note, int>;
|
||||||
|
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using InkForge.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace InkForge.Sqlite.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(NoteDbContext))]
|
|
||||||
[Migration("20240207000000__01_Initial")]
|
|
||||||
partial class _01_Initial
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.1");
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Blob", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<byte[]>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("BLOB");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Blobs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteEntity", b =>
|
|
||||||
{
|
|
||||||
b.Property<int?>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Notes");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteVersionEntity", b =>
|
|
||||||
{
|
|
||||||
b.Property<int?>("Version")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.HasKey("Version");
|
|
||||||
|
|
||||||
b.HasIndex("Id", "Version")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("NoteVersions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteEntity", b =>
|
|
||||||
{
|
|
||||||
b.OwnsOne("InkForge.Data.Domain.Note", "Value", b1 =>
|
|
||||||
{
|
|
||||||
b1.Property<int>("ParentId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b1.Property<string>("ContentId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Created")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset?>("Deleted")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Updated")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.HasKey("ParentId");
|
|
||||||
|
|
||||||
b1.HasIndex("ContentId");
|
|
||||||
|
|
||||||
b1.ToTable("Notes");
|
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Blob", "Content")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b1.WithOwner("Parent")
|
|
||||||
.HasForeignKey("ParentId");
|
|
||||||
|
|
||||||
b1.Navigation("Content");
|
|
||||||
|
|
||||||
b1.Navigation("Parent");
|
|
||||||
});
|
|
||||||
|
|
||||||
b.Navigation("Value")
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteVersionEntity", b =>
|
|
||||||
{
|
|
||||||
b.OwnsOne("InkForge.Data.Domain.Note", "Value", b1 =>
|
|
||||||
{
|
|
||||||
b1.Property<int>("NoteVersionEntityVersion")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b1.Property<string>("ContentId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Created")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset?>("Deleted")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Updated")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.HasKey("NoteVersionEntityVersion");
|
|
||||||
|
|
||||||
b1.HasIndex("ContentId");
|
|
||||||
|
|
||||||
b1.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b1.ToTable("NoteVersions");
|
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Blob", "Content")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b1.WithOwner()
|
|
||||||
.HasForeignKey("NoteVersionEntityVersion");
|
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Infrastructure.NoteEntity", "Parent")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ParentId");
|
|
||||||
|
|
||||||
b1.Navigation("Content");
|
|
||||||
|
|
||||||
b1.Navigation("Parent");
|
|
||||||
});
|
|
||||||
|
|
||||||
b.Navigation("Value")
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using InkForge.Data;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace InkForge.Sqlite.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(NoteDbContext))]
|
|
||||||
[Migration("20240214000000__02_Metadata")]
|
|
||||||
partial class _02_Metadata
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.2");
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Blob", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<byte[]>("Content")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("BLOB");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Blobs");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.MetadataEntity", b =>
|
|
||||||
{
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Metadata");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.MetadataVersionEntity", b =>
|
|
||||||
{
|
|
||||||
b.Property<int?>("Version")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<string>("Id")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.Property<string>("Value")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("Version");
|
|
||||||
|
|
||||||
b.HasIndex("Id", "Version")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("MetadataHistory");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteEntity", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Notes");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteVersionEntity", b =>
|
|
||||||
{
|
|
||||||
b.Property<int?>("Version")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.HasKey("Version");
|
|
||||||
|
|
||||||
b.HasIndex("Id", "Version")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("NoteVersions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteEntity", b =>
|
|
||||||
{
|
|
||||||
b.OwnsOne("InkForge.Data.Domain.Note", "Value", b1 =>
|
|
||||||
{
|
|
||||||
b1.Property<int>("ParentId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b1.Property<string>("ContentId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Created")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset?>("Deleted")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Updated")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.HasKey("ParentId");
|
|
||||||
|
|
||||||
b1.HasIndex("ContentId");
|
|
||||||
|
|
||||||
b1.ToTable("Notes");
|
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Blob", "Content")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b1.WithOwner("Parent")
|
|
||||||
.HasForeignKey("ParentId");
|
|
||||||
|
|
||||||
b1.Navigation("Content");
|
|
||||||
|
|
||||||
b1.Navigation("Parent");
|
|
||||||
});
|
|
||||||
|
|
||||||
b.Navigation("Value")
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Infrastructure.NoteVersionEntity", b =>
|
|
||||||
{
|
|
||||||
b.OwnsOne("InkForge.Data.Domain.Note", "Value", b1 =>
|
|
||||||
{
|
|
||||||
b1.Property<int>("NoteVersionEntityVersion")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b1.Property<string>("ContentId")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Created")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset?>("Deleted")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<int?>("ParentId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Updated")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.HasKey("NoteVersionEntityVersion");
|
|
||||||
|
|
||||||
b1.HasIndex("ContentId");
|
|
||||||
|
|
||||||
b1.HasIndex("ParentId");
|
|
||||||
|
|
||||||
b1.ToTable("NoteVersions");
|
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Blob", "Content")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ContentId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b1.WithOwner()
|
|
||||||
.HasForeignKey("NoteVersionEntityVersion");
|
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Infrastructure.NoteEntity", "Parent")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ParentId");
|
|
||||||
|
|
||||||
b1.Navigation("Content");
|
|
||||||
|
|
||||||
b1.Navigation("Parent");
|
|
||||||
});
|
|
||||||
|
|
||||||
b.Navigation("Value")
|
|
||||||
.IsRequired();
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace InkForge.Sqlite.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class _02_Metadata : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Metadata",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
Value = table.Column<string>(type: "TEXT", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Metadata", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "MetadataHistory",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Version = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
Value = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
Id = table.Column<string>(type: "TEXT", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_MetadataHistory", x => x.Version);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_MetadataHistory_Id_Version",
|
|
||||||
table: "MetadataHistory",
|
|
||||||
columns: new[] { "Id", "Version" },
|
|
||||||
unique: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Metadata");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "MetadataHistory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
namespace InkForge.Sqlite.Migrations
|
namespace InkForge.Sqlite.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(NoteDbContext))]
|
[DbContext(typeof(NoteDbContext))]
|
||||||
[Migration("20240405000000__03_DropHistory")]
|
[Migration("20240401_Initial")]
|
||||||
partial class _03_DropHistory
|
partial class _20240401_Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
|
@ -22,8 +22,9 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Blob", b =>
|
modelBuilder.Entity("InkForge.Data.Blob", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<int>("Id")
|
||||||
.HasColumnType("TEXT");
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<byte[]>("Value")
|
b.Property<byte[]>("Value")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
|
@ -75,9 +76,8 @@ namespace InkForge.Sqlite.Migrations
|
||||||
b1.Property<int>("NoteEntityId")
|
b1.Property<int>("NoteEntityId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b1.Property<string>("ContentId")
|
b1.Property<int>("ContentId")
|
||||||
.IsRequired()
|
.HasColumnType("INTEGER");
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Created")
|
b1.Property<DateTimeOffset>("Created")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
@ -94,20 +94,19 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
b1.HasKey("NoteEntityId");
|
b1.HasKey("NoteEntityId");
|
||||||
|
|
||||||
b1.HasIndex("ContentId");
|
b1.HasIndex("ContentId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b1.ToTable("Notes");
|
b1.ToTable("Notes");
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Blob", "Content")
|
b1.HasOne("InkForge.Data.Blob", null)
|
||||||
.WithMany()
|
.WithOne()
|
||||||
.HasForeignKey("ContentId")
|
.HasForeignKey("InkForge.Data.NoteEntity.Value#InkForge.Data.Note", "ContentId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b1.WithOwner()
|
b1.WithOwner()
|
||||||
.HasForeignKey("NoteEntityId");
|
.HasForeignKey("NoteEntityId");
|
||||||
|
|
||||||
b1.Navigation("Content");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
b.Navigation("Parent");
|
b.Navigation("Parent");
|
||||||
|
|
@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
namespace InkForge.Sqlite.Migrations
|
namespace InkForge.Sqlite.Migrations
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public partial class _01_Initial : Migration
|
public partial class _20240401_Initial : Migration
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
|
@ -15,25 +15,38 @@ namespace InkForge.Sqlite.Migrations
|
||||||
name: "Blobs",
|
name: "Blobs",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<string>(type: "TEXT", nullable: false),
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
Content = table.Column<byte[]>(type: "BLOB", nullable: false)
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
Value = table.Column<byte[]>(type: "BLOB", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_Blobs", x => x.Id);
|
table.PrimaryKey("PK_Blobs", x => x.Id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Metadata",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
|
Value = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Metadata", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Notes",
|
name: "Notes",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
Id = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
Value_Created = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
Value_Created = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
||||||
|
Value_ContentId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
Value_Deleted = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
|
||||||
Value_Name = table.Column<string>(type: "TEXT", nullable: false),
|
Value_Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
Value_Updated = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
Value_Updated = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
||||||
Value_Deleted = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
|
ParentId = table.Column<int>(type: "INTEGER", nullable: true)
|
||||||
Value_ContentId = table.Column<string>(type: "TEXT", nullable: false)
|
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
|
|
@ -44,65 +57,30 @@ namespace InkForge.Sqlite.Migrations
|
||||||
principalTable: "Blobs",
|
principalTable: "Blobs",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
onDelete: ReferentialAction.Cascade);
|
onDelete: ReferentialAction.Cascade);
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "NoteVersions",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Version = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
Value_Created = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
|
||||||
Value_ParentId = table.Column<int>(type: "INTEGER", nullable: true),
|
|
||||||
Value_Name = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
Value_Updated = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
|
||||||
Value_Deleted = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
|
|
||||||
Value_ContentId = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_NoteVersions", x => x.Version);
|
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_NoteVersions_Blobs_Value_ContentId",
|
name: "FK_Notes_Notes_ParentId",
|
||||||
column: x => x.Value_ContentId,
|
column: x => x.ParentId,
|
||||||
principalTable: "Blobs",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_NoteVersions_Notes_Value_ParentId",
|
|
||||||
column: x => x.Value_ParentId,
|
|
||||||
principalTable: "Notes",
|
principalTable: "Notes",
|
||||||
principalColumn: "Id");
|
principalColumn: "Id");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Notes_ParentId",
|
||||||
|
table: "Notes",
|
||||||
|
column: "ParentId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_Notes_Value_ContentId",
|
name: "IX_Notes_Value_ContentId",
|
||||||
table: "Notes",
|
table: "Notes",
|
||||||
column: "Value_ContentId");
|
column: "Value_ContentId",
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_NoteVersions_Id_Version",
|
|
||||||
table: "NoteVersions",
|
|
||||||
columns: new[] { "Id", "Version" },
|
|
||||||
unique: true);
|
unique: true);
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_NoteVersions_Value_ContentId",
|
|
||||||
table: "NoteVersions",
|
|
||||||
column: "Value_ContentId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_NoteVersions_Value_ParentId",
|
|
||||||
table: "NoteVersions",
|
|
||||||
column: "Value_ParentId");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "NoteVersions");
|
name: "Metadata");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Notes");
|
name: "Notes");
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace InkForge.Sqlite.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class _03_DropHistory : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "MetadataHistory");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "NoteVersions");
|
|
||||||
|
|
||||||
migrationBuilder.RenameColumn(
|
|
||||||
name: "Content",
|
|
||||||
table: "Blobs",
|
|
||||||
newName: "Value");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "Id",
|
|
||||||
table: "Notes",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "INTEGER")
|
|
||||||
.OldAnnotation("Sqlite:Autoincrement", true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "ParentId",
|
|
||||||
table: "Notes",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Notes_ParentId",
|
|
||||||
table: "Notes",
|
|
||||||
column: "ParentId");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Notes_Notes_ParentId",
|
|
||||||
table: "Notes",
|
|
||||||
column: "ParentId",
|
|
||||||
principalTable: "Notes",
|
|
||||||
principalColumn: "Id");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Notes_Notes_ParentId",
|
|
||||||
table: "Notes");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_Notes_ParentId",
|
|
||||||
table: "Notes");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ParentId",
|
|
||||||
table: "Notes");
|
|
||||||
|
|
||||||
migrationBuilder.RenameColumn(
|
|
||||||
name: "Value",
|
|
||||||
table: "Blobs",
|
|
||||||
newName: "Content");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "Id",
|
|
||||||
table: "Notes",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "INTEGER")
|
|
||||||
.Annotation("Sqlite:Autoincrement", true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "MetadataHistory",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Version = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
Id = table.Column<string>(type: "TEXT", nullable: true),
|
|
||||||
Value = table.Column<string>(type: "TEXT", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_MetadataHistory", x => x.Version);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "NoteVersions",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Version = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
Id = table.Column<int>(type: "INTEGER", nullable: false),
|
|
||||||
Value_ContentId = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
Value_ParentId = table.Column<int>(type: "INTEGER", nullable: true),
|
|
||||||
Value_Created = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
|
||||||
Value_Deleted = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
|
|
||||||
Value_Name = table.Column<string>(type: "TEXT", nullable: false),
|
|
||||||
Value_Updated = table.Column<DateTimeOffset>(type: "TEXT", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_NoteVersions", x => x.Version);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_NoteVersions_Blobs_Value_ContentId",
|
|
||||||
column: x => x.Value_ContentId,
|
|
||||||
principalTable: "Blobs",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_NoteVersions_Notes_Value_ParentId",
|
|
||||||
column: x => x.Value_ParentId,
|
|
||||||
principalTable: "Notes",
|
|
||||||
principalColumn: "Id");
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_MetadataHistory_Id_Version",
|
|
||||||
table: "MetadataHistory",
|
|
||||||
columns: new[] { "Id", "Version" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_NoteVersions_Id_Version",
|
|
||||||
table: "NoteVersions",
|
|
||||||
columns: new[] { "Id", "Version" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_NoteVersions_Value_ContentId",
|
|
||||||
table: "NoteVersions",
|
|
||||||
column: "Value_ContentId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_NoteVersions_Value_ParentId",
|
|
||||||
table: "NoteVersions",
|
|
||||||
column: "Value_ParentId");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,8 +19,9 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.Blob", b =>
|
modelBuilder.Entity("InkForge.Data.Blob", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<int>("Id")
|
||||||
.HasColumnType("TEXT");
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<byte[]>("Value")
|
b.Property<byte[]>("Value")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
|
@ -28,7 +29,7 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("Blobs", (string)null);
|
b.ToTable("Blobs");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.MetadataEntity", b =>
|
modelBuilder.Entity("InkForge.Data.MetadataEntity", b =>
|
||||||
|
|
@ -42,7 +43,7 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("Metadata", (string)null);
|
b.ToTable("Metadata");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.NoteEntity", b =>
|
modelBuilder.Entity("InkForge.Data.NoteEntity", b =>
|
||||||
|
|
@ -58,7 +59,7 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
b.HasIndex("ParentId");
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
b.ToTable("Notes", (string)null);
|
b.ToTable("Notes");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("InkForge.Data.NoteEntity", b =>
|
modelBuilder.Entity("InkForge.Data.NoteEntity", b =>
|
||||||
|
|
@ -67,14 +68,13 @@ namespace InkForge.Sqlite.Migrations
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("ParentId");
|
.HasForeignKey("ParentId");
|
||||||
|
|
||||||
b.OwnsOne("InkForge.Data.NoteEntity.Value#InkForge.Data.Note", "Value", b1 =>
|
b.OwnsOne("InkForge.Data.Note", "Value", b1 =>
|
||||||
{
|
{
|
||||||
b1.Property<int>("NoteEntityId")
|
b1.Property<int>("NoteEntityId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b1.Property<string>("ContentId")
|
b1.Property<int>("ContentId")
|
||||||
.IsRequired()
|
.HasColumnType("INTEGER");
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b1.Property<DateTimeOffset>("Created")
|
b1.Property<DateTimeOffset>("Created")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
@ -91,20 +91,19 @@ namespace InkForge.Sqlite.Migrations
|
||||||
|
|
||||||
b1.HasKey("NoteEntityId");
|
b1.HasKey("NoteEntityId");
|
||||||
|
|
||||||
b1.HasIndex("ContentId");
|
b1.HasIndex("ContentId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b1.ToTable("Notes", (string)null);
|
b1.ToTable("Notes");
|
||||||
|
|
||||||
b1.HasOne("InkForge.Data.Blob", "Content")
|
b1.HasOne("InkForge.Data.Blob", null)
|
||||||
.WithMany()
|
.WithOne()
|
||||||
.HasForeignKey("ContentId")
|
.HasForeignKey("InkForge.Data.NoteEntity.Value#InkForge.Data.Note", "ContentId")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b1.WithOwner()
|
b1.WithOwner()
|
||||||
.HasForeignKey("NoteEntityId");
|
.HasForeignKey("NoteEntityId");
|
||||||
|
|
||||||
b1.Navigation("Content");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
b.Navigation("Parent");
|
b.Navigation("Parent");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue