Initial commit
This commit is contained in:
commit
e86b971d62
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
.idea/
|
||||
22
AutoCat.sln
Normal file
22
AutoCat.sln
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoCat", "AutoCat\AutoCat.csproj", "{9FB32BFB-805B-49F2-B5A2-E1F5A0C06A62}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoCatCore", "AutoCatCore\AutoCatCore.csproj", "{39A58D42-E1FA-4442-A7E3-7616D35AC770}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9FB32BFB-805B-49F2-B5A2-E1F5A0C06A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9FB32BFB-805B-49F2-B5A2-E1F5A0C06A62}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9FB32BFB-805B-49F2-B5A2-E1F5A0C06A62}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9FB32BFB-805B-49F2-B5A2-E1F5A0C06A62}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{39A58D42-E1FA-4442-A7E3-7616D35AC770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{39A58D42-E1FA-4442-A7E3-7616D35AC770}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{39A58D42-E1FA-4442-A7E3-7616D35AC770}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{39A58D42-E1FA-4442-A7E3-7616D35AC770}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
6
AutoCat.sln.DotSettings.user
Normal file
6
AutoCat.sln.DotSettings.user
Normal file
@ -0,0 +1,6 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:String>
|
||||
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
||||
<Assembly Path="/Users/selim/.nuget/packages/avalonia/11.0.0/ref/net6.0/Avalonia.Markup.dll" />
|
||||
<Assembly Path="/Users/selim/Documents/dev/AutoCatAvalonia/AutoCat/bin/Debug/net7.0/Avalonia.Base.dll" />
|
||||
</AssemblyExplorer></s:String></wpf:ResourceDictionary>
|
||||
BIN
AutoCat/.DS_Store
vendored
Normal file
BIN
AutoCat/.DS_Store
vendored
Normal file
Binary file not shown.
14
AutoCat/App.axaml
Normal file
14
AutoCat/App.axaml
Normal file
@ -0,0 +1,14 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:AutoCat"
|
||||
x:Class="AutoCat.App"
|
||||
RequestedThemeVariant="Default">
|
||||
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
</Application.DataTemplates>
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme/>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
58
AutoCat/App.axaml.cs
Normal file
58
AutoCat/App.axaml.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using AutoCat.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using AutoCat.ViewModels;
|
||||
using AutoCat.Views;
|
||||
using AutoCatCore.Services.Api;
|
||||
using AutoCatCore.Services.Storage;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace AutoCat;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public IHost AppHost { get; private set; }
|
||||
|
||||
private static void RegisterDependencies(HostBuilderContext context, IServiceCollection services)
|
||||
{
|
||||
// Services
|
||||
services.AddSingleton<IApiService, ApiService>();
|
||||
services.AddSingleton<IStorageService, StorageService>();
|
||||
|
||||
// ViewModels
|
||||
services.AddTransient<AuthWindowViewModel>();
|
||||
services.AddTransient<MainWindowViewModel>();
|
||||
|
||||
// Windows
|
||||
services.AddWindowFactory<AuthWindow>();
|
||||
services.AddWindowFactory<MainWindow>();
|
||||
}
|
||||
|
||||
public App()
|
||||
{
|
||||
AppHost = Host.CreateDefaultBuilder()
|
||||
.ConfigureServices(RegisterDependencies)
|
||||
.Build();
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
var storageService = AppHost.Services.GetRequiredService<IStorageService>();
|
||||
|
||||
desktop.MainWindow = storageService.IsLoggedIn
|
||||
? AppHost.Services.GetRequiredService<MainWindow>()
|
||||
: AppHost.Services.GetRequiredService<AuthWindow>();
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
BIN
AutoCat/Assets/avalonia-logo.ico
Normal file
BIN
AutoCat/Assets/avalonia-logo.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
34
AutoCat/AutoCat.csproj
Normal file
34
AutoCat/AutoCat.csproj
Normal file
@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>false</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="Avalonia.Themes.Fluent" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AutoCatCore\AutoCatCore.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
31
AutoCat/Extensions/TernaryExtension.cs
Normal file
31
AutoCat/Extensions/TernaryExtension.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Markup.Xaml.MarkupExtensions;
|
||||
|
||||
namespace AutoCat.Extensions;
|
||||
|
||||
public class TernaryExtension : MarkupExtension
|
||||
{
|
||||
public TernaryExtension()
|
||||
{
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public object True { get; set; }
|
||||
|
||||
public object False { get; set; }
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
var binding = new ReflectionBindingExtension(Path)
|
||||
{
|
||||
Mode = BindingMode.OneWay,
|
||||
Converter = new FuncValueConverter<bool, object>(e => e ? True : False)
|
||||
};
|
||||
|
||||
return binding.ProvideValue(serviceProvider);
|
||||
}
|
||||
}
|
||||
12
AutoCat/Mocks/AuthWindowViewModelMock.cs
Normal file
12
AutoCat/Mocks/AuthWindowViewModelMock.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Reactive;
|
||||
using AutoCat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace AutoCat.Mocks;
|
||||
|
||||
public class AuthWindowViewModelMock: ViewModelBase
|
||||
{
|
||||
public string Email { get; set; } = "";
|
||||
public string Password { get; set; } = "";
|
||||
public ReactiveCommand<Unit, Unit> LoginCommand { get; } = ReactiveCommand.Create(() => { });
|
||||
}
|
||||
22
AutoCat/Program.cs
Normal file
22
AutoCat/Program.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Avalonia;
|
||||
using Avalonia.ReactiveUI;
|
||||
using System;
|
||||
|
||||
namespace AutoCat;
|
||||
|
||||
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<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI();
|
||||
}
|
||||
23
AutoCat/Utils/AbstractFactory.cs
Normal file
23
AutoCat/Utils/AbstractFactory.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace AutoCat.Utils;
|
||||
|
||||
public interface IAbstractFactory<out T>
|
||||
{
|
||||
T Create();
|
||||
}
|
||||
|
||||
public class AbstractFactory<T> : IAbstractFactory<T>
|
||||
{
|
||||
private readonly Func<T> _factory;
|
||||
|
||||
public AbstractFactory(Func<T> factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public T Create()
|
||||
{
|
||||
return _factory();
|
||||
}
|
||||
}
|
||||
15
AutoCat/Utils/DIExtentions.cs
Normal file
15
AutoCat/Utils/DIExtentions.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AutoCat.Utils;
|
||||
|
||||
public static class DependencyInjectionExtensions
|
||||
{
|
||||
public static void AddWindowFactory<TWindow>(this IServiceCollection services) where TWindow: Window
|
||||
{
|
||||
services.AddTransient<TWindow>();
|
||||
services.AddSingleton<Func<TWindow>>(x => () => x.GetService<TWindow>()!);
|
||||
services.AddSingleton<IAbstractFactory<TWindow>, AbstractFactory<TWindow>>();
|
||||
}
|
||||
}
|
||||
24
AutoCat/Utils/ViewModelProvider.cs
Normal file
24
AutoCat/Utils/ViewModelProvider.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace AutoCat.Utils;
|
||||
|
||||
public class ViewModelProvider: MarkupExtension
|
||||
{
|
||||
private readonly Type _viewModelType;
|
||||
|
||||
public ViewModelProvider(Type viewModelType)
|
||||
{
|
||||
_viewModelType = viewModelType;
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (Application.Current is App app)
|
||||
return app.AppHost.Services.GetService(_viewModelType)
|
||||
?? throw new Exception("Error finding ViewModel");
|
||||
else
|
||||
throw new Exception("Error getting App instance");
|
||||
}
|
||||
}
|
||||
27
AutoCat/ViewLocator.cs
Normal file
27
AutoCat/ViewLocator.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using AutoCat.ViewModels;
|
||||
|
||||
namespace AutoCat;
|
||||
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
public Control Build(object data)
|
||||
{
|
||||
var name = data.GetType().FullName!.Replace("ViewModel", "View");
|
||||
var type = Type.GetType(name);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
return (Control)Activator.CreateInstance(type)!;
|
||||
}
|
||||
|
||||
return new TextBlock { Text = "Not Found: " + name };
|
||||
}
|
||||
|
||||
public bool Match(object data)
|
||||
{
|
||||
return data is ViewModelBase;
|
||||
}
|
||||
}
|
||||
83
AutoCat/ViewModels/AuthWindowViewModel.cs
Normal file
83
AutoCat/ViewModels/AuthWindowViewModel.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Threading.Tasks;
|
||||
using AutoCatCore.Services.Api;
|
||||
using AutoCatCore.Services.Storage;
|
||||
using ReactiveUI;
|
||||
using MsBox.Avalonia;
|
||||
using MsBox.Avalonia.Dto;
|
||||
using MsBox.Avalonia.Enums;
|
||||
|
||||
namespace AutoCat.ViewModels;
|
||||
|
||||
public class AuthWindowViewModel: ViewModelBase
|
||||
{
|
||||
#region Dependencies
|
||||
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IStorageService _storageService;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
private string _email = "";
|
||||
private string _password = "";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
set => this.RaiseAndSetIfChanged(ref _email, value);
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => _password;
|
||||
set => this.RaiseAndSetIfChanged(ref _password, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Commands
|
||||
|
||||
public ReactiveCommand<Unit, Unit> LoginCommand { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
public AuthWindowViewModel(IApiService apiService, IStorageService storageService)
|
||||
{
|
||||
_apiService = apiService;
|
||||
_storageService = storageService;
|
||||
|
||||
var loginEnabled = this.WhenAnyValue(
|
||||
vm => vm.Email,
|
||||
vm => vm.Password,
|
||||
(login, password) => login.Length > 3 && password.Length > 3);
|
||||
|
||||
LoginCommand = ReactiveCommand.CreateFromTask(Login, loginEnabled);
|
||||
LoginCommand.ThrownExceptions.Subscribe(ShowError);
|
||||
}
|
||||
|
||||
private async Task Login()
|
||||
{
|
||||
var user = await _apiService.Login(Email, Password);
|
||||
//await _storageService.SetUser(user);
|
||||
Close();
|
||||
}
|
||||
|
||||
private async void ShowError(Exception error)
|
||||
{
|
||||
var msgBox = MessageBoxManager.GetMessageBoxStandard(new MessageBoxStandardParams
|
||||
{
|
||||
ButtonDefinitions = ButtonEnum.Ok,
|
||||
ContentTitle = "Error",
|
||||
ContentMessage = error.Message
|
||||
});
|
||||
|
||||
await msgBox.ShowAsync();
|
||||
}
|
||||
}
|
||||
6
AutoCat/ViewModels/MainWindowViewModel.cs
Normal file
6
AutoCat/ViewModels/MainWindowViewModel.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace AutoCat.ViewModels;
|
||||
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
{
|
||||
public string Greeting => "Welcome to Avalonia!";
|
||||
}
|
||||
14
AutoCat/ViewModels/ViewModelBase.cs
Normal file
14
AutoCat/ViewModels/ViewModelBase.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace AutoCat.ViewModels;
|
||||
|
||||
public class ViewModelBase : ReactiveObject
|
||||
{
|
||||
public event EventHandler? ClosingRequest;
|
||||
|
||||
protected void Close()
|
||||
{
|
||||
ClosingRequest?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
37
AutoCat/Views/AuthWindow.axaml
Normal file
37
AutoCat/Views/AuthWindow.axaml
Normal file
@ -0,0 +1,37 @@
|
||||
<Window 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:AutoCat.ViewModels"
|
||||
xmlns:utils="using:AutoCat.Utils"
|
||||
xmlns:mocks="using:AutoCat.Mocks"
|
||||
xmlns:ext="using:AutoCat.Extensions"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="AutoCat.Views.AuthWindow"
|
||||
x:DataType="vm:AuthWindowViewModel"
|
||||
Title="AuthWindow"
|
||||
Width="800" Height="600"
|
||||
DataContext="{utils:ViewModelProvider vm:AuthWindowViewModel}">
|
||||
|
||||
<Design.DataContext>
|
||||
<mocks:AuthWindowViewModelMock/>
|
||||
</Design.DataContext>
|
||||
|
||||
<StackPanel Orientation="Vertical"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="100, 0"
|
||||
Spacing="16">
|
||||
<TextBox Watermark="Email"
|
||||
Text="{Binding Email}"
|
||||
IsEnabled="{Binding !LoginCommand.IsExecuting^}"/>
|
||||
<TextBox Watermark="Password" PasswordChar="*"
|
||||
Text="{Binding Password}"
|
||||
IsEnabled="{Binding !LoginCommand.IsExecuting^}"/>
|
||||
<Button Content="{ext:Ternary Path=LoginCommand.IsExecuting^, True=Logging In..., False=Log In}"
|
||||
Command="{Binding LoginCommand}"
|
||||
IsEnabled="{Binding !LoginCommand.IsExecuting^}"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
20
AutoCat/Views/AuthWindow.axaml.cs
Normal file
20
AutoCat/Views/AuthWindow.axaml.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using AutoCat.ViewModels;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace AutoCat.Views;
|
||||
|
||||
public partial class AuthWindow : Window
|
||||
{
|
||||
public AuthWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (DataContext is ViewModelBase vm)
|
||||
{
|
||||
vm.ClosingRequest += (sender, args) =>
|
||||
{
|
||||
Close();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
22
AutoCat/Views/MainWindow.axaml
Normal file
22
AutoCat/Views/MainWindow.axaml
Normal file
@ -0,0 +1,22 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:AutoCat.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
Width="800"
|
||||
Height="600"
|
||||
x:Class="AutoCat.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Title="AutoCat">
|
||||
|
||||
<Design.DataContext>
|
||||
<!-- This only sets the DataContext for the previewer in an IDE,
|
||||
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
|
||||
<vm:MainWindowViewModel/>
|
||||
</Design.DataContext>
|
||||
|
||||
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
|
||||
</Window>
|
||||
11
AutoCat/Views/MainWindow.axaml.cs
Normal file
11
AutoCat/Views/MainWindow.axaml.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace AutoCat.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
18
AutoCat/app.manifest
Normal file
18
AutoCat/app.manifest
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<!-- This manifest is used on Windows only.
|
||||
Don't remove it as it might cause problems with window transparency and embeded controls.
|
||||
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||
<assemblyIdentity version="1.0.0.0" name="AvaloniaTest.Desktop"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
BIN
AutoCatCore/.DS_Store
vendored
Normal file
BIN
AutoCatCore/.DS_Store
vendored
Normal file
Binary file not shown.
14
AutoCatCore/AutoCatCore.csproj
Normal file
14
AutoCatCore/AutoCatCore.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
19
AutoCatCore/Model/AutoCatDbContext.cs
Normal file
19
AutoCatCore/Model/AutoCatDbContext.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
class AutoCatDbContext: DbContext
|
||||
{
|
||||
public DbSet<User> Users { get; private set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseSqlite("filename=autocat.db");
|
||||
}
|
||||
}
|
||||
}
|
||||
16
AutoCatCore/Model/Osago.cs
Normal file
16
AutoCatCore/Model/Osago.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class Osago
|
||||
{
|
||||
public double Date { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string Vin { get; set; }
|
||||
public string PlateNumber { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Status { get; set; }
|
||||
public string Restrictions { get; set; }
|
||||
public string Insurant { get; set; }
|
||||
public string Owner { get; set; }
|
||||
public string UsageRegion { get; set; }
|
||||
}
|
||||
}
|
||||
14
AutoCatCore/Model/Requests/Credentials.cs
Normal file
14
AutoCatCore/Model/Requests/Credentials.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoCat.Model.Requests
|
||||
{
|
||||
class Credentials
|
||||
{
|
||||
public string Email { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
13
AutoCatCore/Model/Requests/PagedResponse.cs
Normal file
13
AutoCatCore/Model/Requests/PagedResponse.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace AutoCatCore.Model.Requests
|
||||
{
|
||||
public class PagedResponse<T>
|
||||
{
|
||||
public int? Count { get; set; }
|
||||
public string PageToken { get; set; }
|
||||
public List<T> Items { get; set; }
|
||||
}
|
||||
}
|
||||
8
AutoCatCore/Model/Requests/Response.cs
Normal file
8
AutoCatCore/Model/Requests/Response.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace AutoCatCore.Model.Requests;
|
||||
|
||||
internal class Response<T>
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public T? Data { get; set; }
|
||||
public string? Error { get; set; }
|
||||
}
|
||||
16
AutoCatCore/Model/User.cs
Normal file
16
AutoCatCore/Model/User.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class User
|
||||
{
|
||||
[Key]
|
||||
public string Email { get; set; }
|
||||
public string? Token { get; set; }
|
||||
[JsonIgnore]
|
||||
public string? FirebaseIdToken { get; set; }
|
||||
[JsonIgnore]
|
||||
public string? FirebaseRefreshToken { get; set; }
|
||||
}
|
||||
}
|
||||
31
AutoCatCore/Model/Vehicle.cs
Normal file
31
AutoCatCore/Model/Vehicle.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class Vehicle
|
||||
{
|
||||
[Key]
|
||||
public string Number { get; set; }
|
||||
public string CurrentNumber { get; set; }
|
||||
public string Vin1 { get; set; }
|
||||
public string Vin2 { get; set; }
|
||||
public string Sts { get; set; }
|
||||
public string Pts { get; set; }
|
||||
public VehicleBrand Brand { get; set; }
|
||||
public VehicleModel Model { get; set; }
|
||||
public string Color { get; set; }
|
||||
public int Year { get; set; }
|
||||
public string Category { get; set; }
|
||||
public bool? IsRightWheel { get; set; }
|
||||
public bool? IsJapanese { get; set; }
|
||||
public double AddedDate { get; set; }
|
||||
public double UpdatedDate { get; set; }
|
||||
public string AddedBy { get; set; }
|
||||
public VehicleEngine Engine { get; set; }
|
||||
public List<VehiclePhoto> Photos { get; set; }
|
||||
public List<VehicleEvent> Events { get; set; }
|
||||
public List<Osago> OsagoContracts { get; set; } = new List<Osago>();
|
||||
public List<VehicleOwnershipPeriod> OwnershipPeriods { get; set; } = new List<VehicleOwnershipPeriod>();
|
||||
public List<VehicleAd> Ads { get; set; }
|
||||
}
|
||||
}
|
||||
18
AutoCatCore/Model/VehicleAd.cs
Normal file
18
AutoCatCore/Model/VehicleAd.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleAd
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Price { get; set; }
|
||||
public double Date { get; set; }
|
||||
public string Mileage { get; set; }
|
||||
public string Region { get; set; }
|
||||
public string City { get; set; }
|
||||
public string AdDescription { get; set; }
|
||||
public List<string> Photos { get; set; }
|
||||
}
|
||||
}
|
||||
8
AutoCatCore/Model/VehicleBrand.cs
Normal file
8
AutoCatCore/Model/VehicleBrand.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleBrand
|
||||
{
|
||||
public VehicleName Name { get; set; }
|
||||
public string Logo { get; set; }
|
||||
}
|
||||
}
|
||||
11
AutoCatCore/Model/VehicleEngine.cs
Normal file
11
AutoCatCore/Model/VehicleEngine.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleEngine
|
||||
{
|
||||
public string Number { get; set; }
|
||||
public int? Volume { get; set; }
|
||||
public double? PowerKw { get; set; }
|
||||
public double? PowerHp { get; set; }
|
||||
public string FuelType { get; set; }
|
||||
}
|
||||
}
|
||||
14
AutoCatCore/Model/VehicleEvent.cs
Normal file
14
AutoCatCore/Model/VehicleEvent.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleEvent
|
||||
{
|
||||
[Key]
|
||||
public string Id { get; set; }
|
||||
public double Date { get; set; }
|
||||
public double Latitude { get; set; }
|
||||
public double Longitude { get; set; }
|
||||
public string Address { get; set; }
|
||||
}
|
||||
}
|
||||
7
AutoCatCore/Model/VehicleModel.cs
Normal file
7
AutoCatCore/Model/VehicleModel.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleModel
|
||||
{
|
||||
public VehicleName Name { get; set; }
|
||||
}
|
||||
}
|
||||
8
AutoCatCore/Model/VehicleName.cs
Normal file
8
AutoCatCore/Model/VehicleName.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleName
|
||||
{
|
||||
public string Original { get; set; }
|
||||
public string Normalized { get; set; }
|
||||
}
|
||||
}
|
||||
17
AutoCatCore/Model/VehicleOwnershipPeriod.cs
Normal file
17
AutoCatCore/Model/VehicleOwnershipPeriod.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehicleOwnershipPeriod
|
||||
{
|
||||
public string LastOperation { get; set; }
|
||||
public string OwnerType { get; set; }
|
||||
public Int64 From { get; set; }
|
||||
public Int64 To { get; set; }
|
||||
public string Region { get; set; }
|
||||
public string RegistrationRegion { get; set; }
|
||||
public string Locality { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string Street { get; set; }
|
||||
public string Building { get; set; }
|
||||
public string Inn { get; set; }
|
||||
}
|
||||
}
|
||||
10
AutoCatCore/Model/VehiclePhoto.cs
Normal file
10
AutoCatCore/Model/VehiclePhoto.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace AutoCatCore.Model
|
||||
{
|
||||
public class VehiclePhoto
|
||||
{
|
||||
public string Brand { get; set; }
|
||||
public string Model { get; set; }
|
||||
public double Date { get; set; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
63
AutoCatCore/Services/Api/ApiService.cs
Normal file
63
AutoCatCore/Services/Api/ApiService.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using AutoCat.Model.Requests;
|
||||
using AutoCatCore.Model;
|
||||
using AutoCatCore.Model.Requests;
|
||||
|
||||
namespace AutoCatCore.Services.Api;
|
||||
|
||||
public class ApiService : IApiService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public ApiService()
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.BaseAddress = new Uri("https://vps.aliencat.pro:8443");
|
||||
}
|
||||
|
||||
private static T GetDataOrThrow<T>(string response)
|
||||
{
|
||||
var resp = JsonSerializer.Deserialize<Response<T>>(response, new JsonSerializerOptions {
|
||||
PropertyNameCaseInsensitive = true
|
||||
});
|
||||
|
||||
if (resp is null)
|
||||
throw new Exception("Error deserializing response");
|
||||
|
||||
if (resp.Success)
|
||||
return resp.Data ?? throw new Exception("Empty response");
|
||||
|
||||
throw new Exception(resp.Error);
|
||||
}
|
||||
|
||||
private void SetAccessToken(string? token)
|
||||
{
|
||||
if (token is null)
|
||||
return;
|
||||
|
||||
_httpClient.DefaultRequestHeaders.Remove("Authorization");
|
||||
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
|
||||
}
|
||||
|
||||
public async Task<User> Login(string email, string password)
|
||||
{
|
||||
var credentials = new Credentials { Email = email, Password = password };
|
||||
var json = JsonSerializer.Serialize(credentials, new JsonSerializerOptions {
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
});
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
var response = await _httpClient.PostAsync("user/login", content);
|
||||
var respStr = await response.Content.ReadAsStringAsync();
|
||||
var result = GetDataOrThrow<User>(respStr);
|
||||
SetAccessToken(result.Token);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<PagedResponse<Vehicle>> GetVehicles()
|
||||
{
|
||||
var response = await _httpClient.GetAsync("vehicles");
|
||||
var respStr = await response.Content.ReadAsStringAsync();
|
||||
return GetDataOrThrow<PagedResponse<Vehicle>>(respStr);
|
||||
}
|
||||
}
|
||||
10
AutoCatCore/Services/Api/IApiService.cs
Normal file
10
AutoCatCore/Services/Api/IApiService.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using AutoCatCore.Model;
|
||||
using AutoCatCore.Model.Requests;
|
||||
|
||||
namespace AutoCatCore.Services.Api;
|
||||
|
||||
public interface IApiService
|
||||
{
|
||||
Task<User> Login(string email, string password);
|
||||
Task<PagedResponse<Vehicle>> GetVehicles();
|
||||
}
|
||||
10
AutoCatCore/Services/Storage/IStorageService.cs
Normal file
10
AutoCatCore/Services/Storage/IStorageService.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using AutoCatCore.Model;
|
||||
|
||||
namespace AutoCatCore.Services.Storage;
|
||||
|
||||
public interface IStorageService
|
||||
{
|
||||
public bool IsLoggedIn { get; }
|
||||
|
||||
public Task SetUser(User user);
|
||||
}
|
||||
33
AutoCatCore/Services/Storage/StorageService.cs
Normal file
33
AutoCatCore/Services/Storage/StorageService.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using AutoCatCore.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AutoCatCore.Services.Storage;
|
||||
|
||||
public class StorageService: IStorageService
|
||||
{
|
||||
private readonly AutoCatDbContext _dbContext;
|
||||
|
||||
public bool IsLoggedIn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_dbContext.Users.Any())
|
||||
return _dbContext.Users.First().Token != null;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetUser(User user)
|
||||
{
|
||||
await _dbContext.Users.ExecuteDeleteAsync();
|
||||
await _dbContext.Users.AddAsync(user);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public StorageService()
|
||||
{
|
||||
_dbContext = new AutoCatDbContext();
|
||||
_dbContext.Database.EnsureCreated();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user