From ad5bedf3394a00bbfc2c08eabf556294b71120bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Thu, 31 Mar 2022 15:35:33 +0000 Subject: [PATCH] Base project --- .../DependencyInjection.cs | 16 +++ .../FileTime.App.DependencyInjection.csproj | 15 +++ .../Behaviors/IOnContainerEnter.cs | 7 ++ .../Enums/AbsolutePathType.cs | 9 ++ .../Enums/SupportsDelete.cs | 9 ++ .../FileTime.Core.Abstraction.csproj | 13 +++ .../Models/FullName.cs | 4 + .../Models/IAbsolutePath.cs | 13 +++ .../Models/IContainer.cs | 7 ++ .../Models/IElement.cs | 7 ++ .../Models/IFileElement.cs | 7 ++ .../FileTime.Core.Abstraction/Models/IItem.cs | 18 ++++ .../Models/NativePath.cs | 4 + .../Services/IContentProvider.cs | 12 +++ .../Services/ITab.cs | 7 ++ src/Core/FileTime.Core.Models/AbsolutePath.cs | 22 ++++ src/Core/FileTime.Core.Models/Constants.cs | 8 ++ src/Core/FileTime.Core.Models/Container.cs | 17 +++ src/Core/FileTime.Core.Models/Element.cs | 16 +++ .../FileTime.Core.Models.csproj | 13 +++ .../ContentProviderBase.cs | 41 ++++++++ .../FileTime.Core.Services.csproj | 18 ++++ src/Core/FileTime.Core.Services/Tab.cs | 7 ++ src/FileTime.sln | 76 ++++++++++++++ src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml | 11 ++ .../Avalonia/FileTime.GuiApp/App.axaml.cs | 29 +++++ .../FileTime.GuiApp/Assets/filetime.ico | Bin 0 -> 33552 bytes .../FileTime.GuiApp/FileTime.GuiApp.csproj | 36 +++++++ .../Avalonia/FileTime.GuiApp/Program.cs | 23 ++++ .../ViewModels/MainWindowViewModel.cs | 10 ++ .../FileTime.GuiApp/Views/MainWindow.axaml | 17 +++ .../FileTime.GuiApp/Views/MainWindow.axaml.cs | 12 +++ .../FileTime.Providers.Local.csproj | 19 ++++ .../LocalContentProvider.cs | 99 ++++++++++++++++++ .../FileTime.Providers.Local/Startup.cs | 15 +++ 35 files changed, 637 insertions(+) create mode 100644 src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs create mode 100644 src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj create mode 100644 src/Core/FileTime.Core.Abstraction/Behaviors/IOnContainerEnter.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Enums/AbsolutePathType.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Enums/SupportsDelete.cs create mode 100644 src/Core/FileTime.Core.Abstraction/FileTime.Core.Abstraction.csproj create mode 100644 src/Core/FileTime.Core.Abstraction/Models/FullName.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Models/IAbsolutePath.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Models/IContainer.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Models/IElement.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Models/IItem.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Models/NativePath.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Services/IContentProvider.cs create mode 100644 src/Core/FileTime.Core.Abstraction/Services/ITab.cs create mode 100644 src/Core/FileTime.Core.Models/AbsolutePath.cs create mode 100644 src/Core/FileTime.Core.Models/Constants.cs create mode 100644 src/Core/FileTime.Core.Models/Container.cs create mode 100644 src/Core/FileTime.Core.Models/Element.cs create mode 100644 src/Core/FileTime.Core.Models/FileTime.Core.Models.csproj create mode 100644 src/Core/FileTime.Core.Services/ContentProviderBase.cs create mode 100644 src/Core/FileTime.Core.Services/FileTime.Core.Services.csproj create mode 100644 src/Core/FileTime.Core.Services/Tab.cs create mode 100644 src/FileTime.sln create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/Assets/filetime.ico create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/FileTime.GuiApp.csproj create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml create mode 100644 src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs create mode 100644 src/Providers/FileTime.Providers.Local/FileTime.Providers.Local.csproj create mode 100644 src/Providers/FileTime.Providers.Local/LocalContentProvider.cs create mode 100644 src/Providers/FileTime.Providers.Local/Startup.cs diff --git a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs new file mode 100644 index 0000000..3a4e9ea --- /dev/null +++ b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs @@ -0,0 +1,16 @@ +using FileTime.Providers.Local; +using Microsoft.Extensions.DependencyInjection; + +namespace FileTime.App.DependencyInjection +{ + public static class DependencyInjection + { + public static IServiceCollection RegisterDefaultServices(IServiceCollection? serviceCollection = null) + { + serviceCollection ??= new ServiceCollection(); + + return serviceCollection + .AddLocalServices(); + } + } +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj b/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj new file mode 100644 index 0000000..9252fe1 --- /dev/null +++ b/src/AppCommon/FileTime.App.DependencyInjection/FileTime.App.DependencyInjection.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + enable + + + + + + + + + diff --git a/src/Core/FileTime.Core.Abstraction/Behaviors/IOnContainerEnter.cs b/src/Core/FileTime.Core.Abstraction/Behaviors/IOnContainerEnter.cs new file mode 100644 index 0000000..47bc880 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Behaviors/IOnContainerEnter.cs @@ -0,0 +1,7 @@ +namespace FileTime.Core.Behaviors +{ + public interface IOnContainerEnter + { + Task OnEnter(); + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Enums/AbsolutePathType.cs b/src/Core/FileTime.Core.Abstraction/Enums/AbsolutePathType.cs new file mode 100644 index 0000000..8ea7f63 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Enums/AbsolutePathType.cs @@ -0,0 +1,9 @@ +namespace FileTime.Core.Enums +{ + public enum AbsolutePathType + { + Unknown, + Container, + Element + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Enums/SupportsDelete.cs b/src/Core/FileTime.Core.Abstraction/Enums/SupportsDelete.cs new file mode 100644 index 0000000..ce052d5 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Enums/SupportsDelete.cs @@ -0,0 +1,9 @@ +namespace FileTime.Core.Enums +{ + public enum SupportsDelete + { + False, + True, + HardDeleteOnly, + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/FileTime.Core.Abstraction.csproj b/src/Core/FileTime.Core.Abstraction/FileTime.Core.Abstraction.csproj new file mode 100644 index 0000000..f2d4187 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/FileTime.Core.Abstraction.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/Core/FileTime.Core.Abstraction/Models/FullName.cs b/src/Core/FileTime.Core.Abstraction/Models/FullName.cs new file mode 100644 index 0000000..128f48d --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/FullName.cs @@ -0,0 +1,4 @@ +namespace FileTime.Core.Models +{ + public record FullName(string Path); +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IAbsolutePath.cs b/src/Core/FileTime.Core.Abstraction/Models/IAbsolutePath.cs new file mode 100644 index 0000000..7cc5837 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/IAbsolutePath.cs @@ -0,0 +1,13 @@ +using FileTime.Core.Enums; +using FileTime.Core.Services; + +namespace FileTime.Core.Models +{ + public interface IAbsolutePath + { + IContentProvider ContentProvider { get; } + IContentProvider? VirtualContentProvider { get; } + FullName Path { get; } + AbsolutePathType Type { get; } + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IContainer.cs b/src/Core/FileTime.Core.Abstraction/Models/IContainer.cs new file mode 100644 index 0000000..e5922a7 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/IContainer.cs @@ -0,0 +1,7 @@ +namespace FileTime.Core.Models +{ + public interface IContainer : IItem + { + IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IElement.cs b/src/Core/FileTime.Core.Abstraction/Models/IElement.cs new file mode 100644 index 0000000..cb68137 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/IElement.cs @@ -0,0 +1,7 @@ +namespace FileTime.Core.Models +{ + public interface IElement : IItem + { + + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs b/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs new file mode 100644 index 0000000..1c907bd --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/IFileElement.cs @@ -0,0 +1,7 @@ +namespace FileTime.Core.Models +{ + public interface IFileElement : IElement + { + + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/IItem.cs b/src/Core/FileTime.Core.Abstraction/Models/IItem.cs new file mode 100644 index 0000000..a04964c --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/IItem.cs @@ -0,0 +1,18 @@ +using FileTime.Core.Enums; +using FileTime.Core.Services; + +namespace FileTime.Core.Models +{ + public interface IItem + { + string Name { get; } + string DisplayName { get; } + FullName? FullName { get; } + NativePath? NativePath { get; } + bool IsHidden { get; } + bool IsExists { get; } + SupportsDelete CanDelete { get; } + bool CanRename { get; } + IContentProvider Provider { get; } + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/NativePath.cs b/src/Core/FileTime.Core.Abstraction/Models/NativePath.cs new file mode 100644 index 0000000..8f1d703 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Models/NativePath.cs @@ -0,0 +1,4 @@ +namespace FileTime.Core.Models +{ + public record NativePath(string Path); +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Services/IContentProvider.cs b/src/Core/FileTime.Core.Abstraction/Services/IContentProvider.cs new file mode 100644 index 0000000..30df12a --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Services/IContentProvider.cs @@ -0,0 +1,12 @@ +using FileTime.Core.Behaviors; +using FileTime.Core.Models; + +namespace FileTime.Core.Services +{ + public interface IContentProvider : IContainer, IOnContainerEnter + { + Task GetItemByFullNameAsync(FullName fullName); + Task GetItemByNativePathAsync(NativePath nativePath); + Task> GetItemsByContainerAsync(FullName fullName); + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Services/ITab.cs b/src/Core/FileTime.Core.Abstraction/Services/ITab.cs new file mode 100644 index 0000000..7420885 --- /dev/null +++ b/src/Core/FileTime.Core.Abstraction/Services/ITab.cs @@ -0,0 +1,7 @@ +namespace FileTime.Core.Services +{ + public interface ITab + { + + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/AbsolutePath.cs b/src/Core/FileTime.Core.Models/AbsolutePath.cs new file mode 100644 index 0000000..f5f41f0 --- /dev/null +++ b/src/Core/FileTime.Core.Models/AbsolutePath.cs @@ -0,0 +1,22 @@ +using FileTime.Core.Enums; +using FileTime.Core.Services; + +namespace FileTime.Core.Models +{ + public class AbsolutePath : IAbsolutePath + { + public IContentProvider ContentProvider { get; } + public IContentProvider? VirtualContentProvider { get; } + + public FullName Path { get; } + public AbsolutePathType Type { get; } + + public AbsolutePath(IContentProvider contentProvider, FullName path, AbsolutePathType type, IContentProvider? virtualContentProvider = null) + { + ContentProvider = contentProvider; + Path = path; + VirtualContentProvider = virtualContentProvider; + Type = type; + } + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/Constants.cs b/src/Core/FileTime.Core.Models/Constants.cs new file mode 100644 index 0000000..f8d8aaf --- /dev/null +++ b/src/Core/FileTime.Core.Models/Constants.cs @@ -0,0 +1,8 @@ +namespace FileTime.Core.Models +{ + public static class Constants + { + public const char SeparatorChar = '/'; + public const string ContentProviderProtocol = "ctp://"; + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/Container.cs b/src/Core/FileTime.Core.Models/Container.cs new file mode 100644 index 0000000..d0d245f --- /dev/null +++ b/src/Core/FileTime.Core.Models/Container.cs @@ -0,0 +1,17 @@ +using FileTime.Core.Enums; +using FileTime.Core.Services; + +namespace FileTime.Core.Models +{ + public record Container + (string Name, + string DisplayName, + FullName FullName, + NativePath NativePath, + bool IsHidden, + bool IsExists, + SupportsDelete CanDelete, + bool CanRename, + IContentProvider Provider, + IReadOnlyList Items) : IContainer; +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/Element.cs b/src/Core/FileTime.Core.Models/Element.cs new file mode 100644 index 0000000..392ace9 --- /dev/null +++ b/src/Core/FileTime.Core.Models/Element.cs @@ -0,0 +1,16 @@ +using FileTime.Core.Enums; +using FileTime.Core.Services; + +namespace FileTime.Core.Models +{ + public record Element + (string Name, + string DisplayName, + FullName FullName, + NativePath NativePath, + bool IsHidden, + bool IsExists, + SupportsDelete CanDelete, + bool CanRename, + IContentProvider Provider) : IElement; +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Models/FileTime.Core.Models.csproj b/src/Core/FileTime.Core.Models/FileTime.Core.Models.csproj new file mode 100644 index 0000000..72dd3f9 --- /dev/null +++ b/src/Core/FileTime.Core.Models/FileTime.Core.Models.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/src/Core/FileTime.Core.Services/ContentProviderBase.cs b/src/Core/FileTime.Core.Services/ContentProviderBase.cs new file mode 100644 index 0000000..90c97e4 --- /dev/null +++ b/src/Core/FileTime.Core.Services/ContentProviderBase.cs @@ -0,0 +1,41 @@ +using FileTime.Core.Enums; +using FileTime.Core.Models; + +namespace FileTime.Core.Services +{ + public abstract class ContentProviderBase : IContentProvider + { + protected List Items { get; set; } = new List(); + + IReadOnlyList IContainer.Items => Items; + + public string Name { get; } + + public string DisplayName { get; } + + public FullName? FullName => null; + + public NativePath? NativePath => null; + + public bool IsHidden => false; + + public bool IsExists => true; + + public SupportsDelete CanDelete => SupportsDelete.False; + + public bool CanRename => false; + + public IContentProvider Provider => this; + + protected ContentProviderBase(string name) + { + DisplayName = Name = name; + } + + public virtual Task OnEnter() => Task.CompletedTask; + public virtual async Task GetItemByFullNameAsync(FullName fullName) => await GetItemByNativePathAsync(GetNativePath(fullName)); + public abstract Task GetItemByNativePathAsync(NativePath nativePath); + public abstract Task> GetItemsByContainerAsync(FullName fullName); + public abstract NativePath GetNativePath(FullName fullName); + } +} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Services/FileTime.Core.Services.csproj b/src/Core/FileTime.Core.Services/FileTime.Core.Services.csproj new file mode 100644 index 0000000..13eed31 --- /dev/null +++ b/src/Core/FileTime.Core.Services/FileTime.Core.Services.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Core/FileTime.Core.Services/Tab.cs b/src/Core/FileTime.Core.Services/Tab.cs new file mode 100644 index 0000000..78913ad --- /dev/null +++ b/src/Core/FileTime.Core.Services/Tab.cs @@ -0,0 +1,7 @@ +namespace FileTime.Core.Services +{ + public class Tab : ITab + { + + } +} \ No newline at end of file diff --git a/src/FileTime.sln b/src/FileTime.sln new file mode 100644 index 0000000..ad96f6e --- /dev/null +++ b/src/FileTime.sln @@ -0,0 +1,76 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32203.90 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{3324D046-1E05-46B5-B1BA-82910D56B332}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.Core.Abstraction", "Core\FileTime.Core.Abstraction\FileTime.Core.Abstraction.csproj", "{99562652-F633-4496-9932-AF8E614906C4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.Core.Models", "Core\FileTime.Core.Models\FileTime.Core.Models.csproj", "{E4681ADE-BAF7-4903-BD2F-59C144AE5637}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.Core.Services", "Core\FileTime.Core.Services\FileTime.Core.Services.csproj", "{5DEA3A08-62FF-4508-B755-3DABA96FC2B2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GuiApp", "GuiApp", "{8ADCA794-440F-4E8F-B9F2-2A30E54119A7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConsoleApp", "ConsoleApp", "{CAEEAD3C-41EB-405C-ACA9-BA1E4C352549}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AppCommon", "AppCommon", "{A5291117-3001-498B-AC8B-E14F71F72570}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Avalonia", "Avalonia", "{01F231DE-4A65-435F-B4BB-77EE5221890C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.GuiApp", "GuiApp\Avalonia\FileTime.GuiApp\FileTime.GuiApp.csproj", "{C389087E-EB78-4DCD-96AF-F1E2A4DEE0B0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{2FC40FE1-4446-44AB-BF77-00F94D995FA3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.Providers.Local", "Providers\FileTime.Providers.Local\FileTime.Providers.Local.csproj", "{EA3C5B46-3950-4CD6-8FA9-45E17C63DAFA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTime.App.DependencyInjection", "AppCommon\FileTime.App.DependencyInjection\FileTime.App.DependencyInjection.csproj", "{A55F4A86-03ED-4D25-807A-04619A1D9507}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {99562652-F633-4496-9932-AF8E614906C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99562652-F633-4496-9932-AF8E614906C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99562652-F633-4496-9932-AF8E614906C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99562652-F633-4496-9932-AF8E614906C4}.Release|Any CPU.Build.0 = Release|Any CPU + {E4681ADE-BAF7-4903-BD2F-59C144AE5637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4681ADE-BAF7-4903-BD2F-59C144AE5637}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4681ADE-BAF7-4903-BD2F-59C144AE5637}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4681ADE-BAF7-4903-BD2F-59C144AE5637}.Release|Any CPU.Build.0 = Release|Any CPU + {5DEA3A08-62FF-4508-B755-3DABA96FC2B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DEA3A08-62FF-4508-B755-3DABA96FC2B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DEA3A08-62FF-4508-B755-3DABA96FC2B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DEA3A08-62FF-4508-B755-3DABA96FC2B2}.Release|Any CPU.Build.0 = Release|Any CPU + {C389087E-EB78-4DCD-96AF-F1E2A4DEE0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C389087E-EB78-4DCD-96AF-F1E2A4DEE0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C389087E-EB78-4DCD-96AF-F1E2A4DEE0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C389087E-EB78-4DCD-96AF-F1E2A4DEE0B0}.Release|Any CPU.Build.0 = Release|Any CPU + {EA3C5B46-3950-4CD6-8FA9-45E17C63DAFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA3C5B46-3950-4CD6-8FA9-45E17C63DAFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA3C5B46-3950-4CD6-8FA9-45E17C63DAFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA3C5B46-3950-4CD6-8FA9-45E17C63DAFA}.Release|Any CPU.Build.0 = Release|Any CPU + {A55F4A86-03ED-4D25-807A-04619A1D9507}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A55F4A86-03ED-4D25-807A-04619A1D9507}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A55F4A86-03ED-4D25-807A-04619A1D9507}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A55F4A86-03ED-4D25-807A-04619A1D9507}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {99562652-F633-4496-9932-AF8E614906C4} = {3324D046-1E05-46B5-B1BA-82910D56B332} + {E4681ADE-BAF7-4903-BD2F-59C144AE5637} = {3324D046-1E05-46B5-B1BA-82910D56B332} + {5DEA3A08-62FF-4508-B755-3DABA96FC2B2} = {3324D046-1E05-46B5-B1BA-82910D56B332} + {01F231DE-4A65-435F-B4BB-77EE5221890C} = {8ADCA794-440F-4E8F-B9F2-2A30E54119A7} + {C389087E-EB78-4DCD-96AF-F1E2A4DEE0B0} = {01F231DE-4A65-435F-B4BB-77EE5221890C} + {EA3C5B46-3950-4CD6-8FA9-45E17C63DAFA} = {2FC40FE1-4446-44AB-BF77-00F94D995FA3} + {A55F4A86-03ED-4D25-807A-04619A1D9507} = {A5291117-3001-498B-AC8B-E14F71F72570} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {859FB3DF-C60A-46B1-82E5-90274905D1EF} + EndGlobalSection +EndGlobal diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml new file mode 100644 index 0000000..a325e5c --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs new file mode 100644 index 0000000..7a7883f --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs @@ -0,0 +1,29 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; +using FileTime.GuiApp.ViewModels; +using FileTime.GuiApp.Views; + +namespace FileTime.GuiApp +{ + public partial class App : Application + { + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new MainWindow + { + DataContext = new MainWindowViewModel(), + }; + } + + base.OnFrameworkInitializationCompleted(); + } + } +} \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Assets/filetime.ico b/src/GuiApp/Avalonia/FileTime.GuiApp/Assets/filetime.ico new file mode 100644 index 0000000000000000000000000000000000000000..217f28f2be5bd90c86752e1819781582a493126a GIT binary patch literal 33552 zcmeI5e@IZQH7RLiYOiKaLDmln7OvW$+y>Q_tk{+jNSL_>Nh~v3rNh!e1(U~`qMI{qc8=$r>-pY$?tSOnJ>Q=CJ-q9= z-{0qa?tS;Zd!Jqj36LPk$|AJSAUo0ssV0Qv<#G9F1|dIEU4DL4zLAhO=n@KXdCe_^ z&_Qb0>hofRn?u8zu;8l8|gLb|N zg^l&`wac0LI?Nx-ZjH}cf$^5wS~0W7s_$xN^{CM*Ypq14mCdQ+`Qe2@RB}2~jX!^JMFD$N z0iGXTNC=7BR6m6W>{Xr~`Q6>QB{h}<+LM9+zkXu(gjqB1&#@y#Iw6a=4>K-wexm1` zsN{zii<0Bmb!vz%^>i`0PQ~voDKKnEV2Kb=o&HgW1QJOA+~PJ6#25`ifNL_x%ZDE@ zXi4xIKgQ1ykdT2@FMhz$MOe)7bM$7vN}~jv8n5{~y`372=LB4Kub65teldfoLvqE7 z{ezEONUV3$!10R+H*aB|%ZTxu04HYt6Y^WQ@yZ)-%J1jl9L4;vH6GrOvrDk1EQ$K| z2q?=Da9za18+LX{c)9oX2q?S92@CXxlJN2BVFZ-C;?RZ!mO24`-!OhZNBC(r6Z=^Z zS{xpx_!%$Jv#r5o*3Wli_lfK2LT?fq-6zK1XJXK>A%UeqASu37#6chdB!C2v01`j~ zNB{{WoIs-Qm)IwW^%F|~`9lJUr7wQfcWw*|rM}x$vFZ5dX3p1iU*<>0x#K{Xbsg!TOLuytwM-fz@&Q z>vD^ipI`p!qc1%F>G)uMNI-YH>af-Efz|cje>%B!e6T(wfZJb>fX=?9;{)mA{;x+r zeqMh0$7=*w9}t6GpubOgRtPcsuY!a~!tHb>t>(4&{JAbdgb@Q_M9Vym_1iTn~+2X|?{%xU|21FMd*poP4r7VdE;=KChxYvks$#jfCP{L5e0I{atkyV2KoPoH?DXIJFPZ*f&r+K6O*c7sDOd z`wy%o8LJ$x)r09Hrw2$$;mnHTZI>R%tP6MCyJ4!}7|E-2yk6d$+ZBntS=rE5J6U)+ z`*3%48rinY@j5j{iZ(WOzoaxe-MQw}#gzVmGc^y6Pxp@1^^LxJwXSVT>sJ@*>dKx~ z&Cxk)Z%sd?zrUq#qB&z^;*-dIdors`vi47&zu}kSdp>Au&;M&*=f%R#$mi>nG@X3C zH7#Z7n|F=pC-8sF!Ahi1XY!*@R*rw9Y9^Lx(|4GL=ApigX literal 0 HcmV?d00001 diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/FileTime.GuiApp.csproj b/src/GuiApp/Avalonia/FileTime.GuiApp/FileTime.GuiApp.csproj new file mode 100644 index 0000000..a4ccf87 --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/FileTime.GuiApp.csproj @@ -0,0 +1,36 @@ + + + WinExe + net6.0 + enable + + copyused + true + Assets\filetime.ico + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs new file mode 100644 index 0000000..1c8c973 --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs @@ -0,0 +1,23 @@ +using System; +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.ReactiveUI; + +namespace FileTime.GuiApp +{ + class Program + { + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .LogToTrace(); + } +} diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..76038d6 --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FileTime.GuiApp.ViewModels +{ + public class MainWindowViewModel + { + } +} diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml new file mode 100644 index 0000000..71e0c5b --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs new file mode 100644 index 0000000..181d0c0 --- /dev/null +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Views/MainWindow.axaml.cs @@ -0,0 +1,12 @@ +using Avalonia.Controls; + +namespace FileTime.GuiApp.Views +{ + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/src/Providers/FileTime.Providers.Local/FileTime.Providers.Local.csproj b/src/Providers/FileTime.Providers.Local/FileTime.Providers.Local.csproj new file mode 100644 index 0000000..4c5b018 --- /dev/null +++ b/src/Providers/FileTime.Providers.Local/FileTime.Providers.Local.csproj @@ -0,0 +1,19 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + diff --git a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs new file mode 100644 index 0000000..0f9347f --- /dev/null +++ b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs @@ -0,0 +1,99 @@ +using System.Runtime.InteropServices; +using FileTime.Core.Enums; +using FileTime.Core.Models; +using FileTime.Core.Services; + +namespace FileTime.Providers.Local +{ + public class LocalContentProvider : ContentProviderBase + { + protected bool IsCaseInsensitive { get; init; } + public LocalContentProvider() : base("local") + { + IsCaseInsensitive = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + RefreshRootDirectories(); + } + + public override Task OnEnter() + { + RefreshRootDirectories(); + + return Task.CompletedTask; + } + + private void RefreshRootDirectories() + { + var rootDirectories = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + ? new DirectoryInfo("/").GetDirectories() + : Environment.GetLogicalDrives().Select(d => new DirectoryInfo(d)); + + Items.Clear(); + Items.AddRange(rootDirectories.Select(DirectoryToAbsolutePath)); + } + + public override Task GetItemByNativePathAsync(NativePath nativePath) + { + var path = nativePath.Path; + if (Directory.Exists(path)) + { + return Task.FromResult((IItem)DirectoryToContainer(new DirectoryInfo(path))); + } + else if (File.Exists(path)) + { + return Task.FromResult((IItem)FileToElement(new FileInfo(path))); + } + + throw new FileNotFoundException(); + } + + public override Task> GetItemsByContainerAsync(FullName fullName) => Task.FromResult(GetItemsByContainer(fullName)); + public List GetItemsByContainer(FullName fullName) => GetItemsByContainer(new DirectoryInfo(GetNativePath(fullName).Path)); + public List GetItemsByContainer(DirectoryInfo directoryInfo) => directoryInfo.GetDirectories().Select(DirectoryToAbsolutePath).Concat(directoryInfo.GetFiles().Select(FileToAbsolutePath)).ToList(); + + private IAbsolutePath DirectoryToAbsolutePath(DirectoryInfo directoryInfo) + { + var fullName = GetFullName(directoryInfo); + return new AbsolutePath(this, fullName, AbsolutePathType.Container); + } + + private IAbsolutePath FileToAbsolutePath(FileInfo file) + { + var fullName = GetFullName(file); + return new AbsolutePath(this, fullName, AbsolutePathType.Element); + } + + private Container DirectoryToContainer(DirectoryInfo directoryInfo) => + new( + directoryInfo.Name, + directoryInfo.Name, + GetFullName(directoryInfo.FullName), + new(directoryInfo.FullName), + (directoryInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden, + directoryInfo.Exists, + SupportsDelete.True, + true, + this, + GetItemsByContainer(directoryInfo) + ); + + private Element FileToElement(FileInfo fileInfo) => + new( + fileInfo.Name, + fileInfo.Name, + GetFullName(fileInfo), + new(fileInfo.FullName), + (fileInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden, + fileInfo.Exists, + SupportsDelete.True, + true, + this + ); + + private FullName GetFullName(DirectoryInfo directoryInfo) => GetFullName(directoryInfo.FullName); + private FullName GetFullName(FileInfo fileInfo) => GetFullName(fileInfo.FullName); + private FullName GetFullName(NativePath nativePath) => GetFullName(nativePath.Path); + private FullName GetFullName(string nativePath) => new(Name + Constants.SeparatorChar + string.Join(Constants.SeparatorChar, nativePath.Split(Path.DirectorySeparatorChar))); + + public override NativePath GetNativePath(FullName fullName) => new(string.Join(Path.DirectorySeparatorChar, fullName.Path.Split(Constants.SeparatorChar).Skip(1))); + } +} \ No newline at end of file diff --git a/src/Providers/FileTime.Providers.Local/Startup.cs b/src/Providers/FileTime.Providers.Local/Startup.cs new file mode 100644 index 0000000..f01f4da --- /dev/null +++ b/src/Providers/FileTime.Providers.Local/Startup.cs @@ -0,0 +1,15 @@ +using FileTime.Core.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace FileTime.Providers.Local +{ + public static class Startup + { + public static IServiceCollection AddLocalServices(this IServiceCollection serviceCollection) + { + return serviceCollection + .AddSingleton() + .AddSingleton(sp => sp.GetService() ?? throw new Exception($"No {nameof(LocalContentProvider)} instance found")); + } + } +} \ No newline at end of file