diff --git a/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml b/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
index 111cdb0..77363d6 100644
--- a/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
+++ b/.idea/.idea.Flawless-Version-Control/.idea/avalonia.xml
@@ -5,9 +5,17 @@
diff --git a/Flawless-Version-Control.sln.DotSettings.user b/Flawless-Version-Control.sln.DotSettings.user
index 90d91d6..4ad8656 100644
--- a/Flawless-Version-Control.sln.DotSettings.user
+++ b/Flawless-Version-Control.sln.DotSettings.user
@@ -17,14 +17,22 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
+ <AssemblyExplorer>
+ <Assembly Path="C:\Users\Cardi\.nuget\packages\irihi.ursa\1.10.0\lib\net8.0\Ursa.dll" />
+ <Assembly Path="C:\Users\Cardi\.nuget\packages\irihi.ursa.themes.semi\1.10.0\lib\netstandard2.0\Ursa.Themes.Semi.dll" />
+</AssemblyExplorer>
<SessionState ContinuousTestingMode="0" IsActive="True" IsLocked="True" Name="PathValidationTest" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
<TestAncestor>
<TestId>MSTest::5B1CB26D-99F5-491A-B368-7E3552FE67E9::net9.0::Flawless.Abstract.Test.WorkPathTestUnit</TestId>
diff --git a/Flawless.Client/ApiHelper.cs b/Flawless.Client/ApiHelper.cs
deleted file mode 100644
index 765f383..0000000
--- a/Flawless.Client/ApiHelper.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Flawless.Client.Remote;
-using Refit;
-
-namespace Flawless.Client;
-
-public static class ApiHelper
-{
- private static IFlawlessServer? _gateway;
-
- public static void ClearGateway()
- {
- Status = null;
- ServerUrl = null;
- _gateway = null;
- Token = null;
- }
-
- public static async Task SetGatewayAsync(string host)
- {
- var setting = new RefitSettings
- {
- AuthorizationHeaderValueGetter = (req, ct) => ApiHelper.Token != null ?
- Task.FromResult($"Bearer {ApiHelper.Token}") : Task.FromResult(string.Empty)
- };
-
- var tempGateway = RestService.For(host, setting);
- Status = await tempGateway.Status();
- ServerUrl = host;
- _gateway = tempGateway;
- }
-
- public static string? ServerUrl { get; private set; }
-
- public static ServerStatusResponse? Status { get; private set; }
-
- public static TokenInfo? Token { get; set; }
-
- public static bool IsGatewayReady => _gateway != null;
- public static IFlawlessServer Gateway => _gateway ?? throw new InvalidProgramException("Not set gateway yet!");
-
-
- public static bool RequireRefreshToken()
- {
- if (Token == null) return true;
- if (DateTime.UtcNow.AddMinutes(1) > Token.Expiration) return true;
- return false;
- }
-
- public static async ValueTask TryRefreshTokenAsync()
- {
- if (Token == null) return false;
- try { Token = await Gateway.Refresh(Token); }
- catch (Exception e)
- {
- await Console.Error.WriteLineAsync(e.ToString());
- return false;
- }
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/Flawless.Client/App.axaml b/Flawless.Client/App.axaml
index a17c221..6fa1a97 100644
--- a/Flawless.Client/App.axaml
+++ b/Flawless.Client/App.axaml
@@ -1,15 +1,10 @@
-
-
-
-
-
-
+ RequestedThemeVariant="Light">
+
-
-
+
+
\ No newline at end of file
diff --git a/Flawless.Client/App.axaml.cs b/Flawless.Client/App.axaml.cs
index 89f3605..502b146 100644
--- a/Flawless.Client/App.axaml.cs
+++ b/Flawless.Client/App.axaml.cs
@@ -1,8 +1,11 @@
+using System.Reflection;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Flawless.Client.ViewModels;
using Flawless.Client.Views;
+using ReactiveUI;
+using Splat;
namespace Flawless.Client;
@@ -11,13 +14,14 @@ public partial class App : Application
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
+ Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetExecutingAssembly());
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
- desktop.MainWindow = new MainWindowView
+ desktop.MainWindow = new MainWindowView()
{
DataContext = new MainWindowViewModel()
};
diff --git a/Flawless.Client/Flawless.Client.csproj b/Flawless.Client/Flawless.Client.csproj
index fdcdf74..78f5a8a 100644
--- a/Flawless.Client/Flawless.Client.csproj
+++ b/Flawless.Client/Flawless.Client.csproj
@@ -11,13 +11,12 @@
-
+
-
@@ -25,6 +24,9 @@
All
+
+
+
@@ -32,6 +34,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Flawless.Client/Program.cs b/Flawless.Client/Program.cs
index af0733a..4d42e59 100644
--- a/Flawless.Client/Program.cs
+++ b/Flawless.Client/Program.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.ReactiveUI;
using System;
+using Avalonia.Dialogs;
namespace Flawless.Client;
@@ -16,6 +17,7 @@ sealed class Program
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
+ .UseManagedSystemDialogs()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace()
diff --git a/Flawless.Client/Service/Api.cs b/Flawless.Client/Service/Api.cs
new file mode 100644
index 0000000..ebe81e9
--- /dev/null
+++ b/Flawless.Client/Service/Api.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Threading.Tasks;
+using Flawless.Client.Remote;
+using ReactiveUI;
+using Refit;
+
+namespace Flawless.Client.Service;
+
+public class Api
+{
+ #region Instance
+
+ private static Api? _instance;
+
+ public static Api Current => _instance ??= new Api();
+
+ #endregion
+
+ public IObservable IsLoggedIn => _isLoggedIn;
+
+ public IObservable ServerUrl => _serverUrl;
+
+ public IObservable Status => _status;
+
+ public IObservable Token => _token;
+
+ private readonly ReactiveProperty _isLoggedIn = new(false);
+
+ private readonly ReactiveProperty _serverUrl = new(string.Empty);
+
+ private readonly ReactiveProperty _status = new(null);
+
+ private readonly ReactiveProperty _token = new(null);
+
+ #region GatewayConfig
+
+ private IFlawlessServer? _gateway;
+
+ public bool IsGatewayReady => _gateway != null;
+
+ public IFlawlessServer Gateway => _gateway ?? throw new InvalidProgramException("Not set gateway yet!");
+
+ public void ClearGateway()
+ {
+ _gateway = null;
+ _isLoggedIn.Value = false;
+ _status.Value = null;
+ _serverUrl.Value = null;
+ _token.Value = null;
+ }
+
+ public async Task SetGatewayAsync(string host)
+ {
+ var setting = new RefitSettings
+ {
+ AuthorizationHeaderValueGetter = (req, ct) => _token.Value != null ?
+ Task.FromResult($"Bearer {_token}") : Task.FromResult(string.Empty)
+ };
+
+ var tempGateway = RestService.For(host, setting);
+ _status.Value = await tempGateway.Status();
+ _serverUrl.Value = host;
+ _gateway = tempGateway;
+ }
+
+ public async ValueTask LoginAsync(string username, string password)
+ {
+ _token.Value = await _gateway.Login(new LoginRequest
+ {
+ Username = username,
+ Password = password
+ });
+
+ _isLoggedIn.Value = true;
+ }
+
+ #endregion
+
+ #region TokenOperations
+
+ public bool RequireRefreshToken()
+ {
+ if (_token.Value == null) return true;
+ if (DateTime.UtcNow.AddMinutes(1) > _token.Value.Expiration) return true;
+ return false;
+ }
+
+ public async ValueTask TryRefreshTokenAsync()
+ {
+ if (_token.Value == null) return false;
+ try { _token.Value = await Gateway.Refresh(_token.Value); }
+ catch (Exception e)
+ {
+ await Console.Error.WriteLineAsync(e.ToString());
+ return false;
+ }
+
+ return true;
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/Flawless.Client/ViewLocator.cs b/Flawless.Client/ViewLocator.cs
deleted file mode 100644
index 39a0d91..0000000
--- a/Flawless.Client/ViewLocator.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using Avalonia.Controls;
-using Avalonia.Controls.Templates;
-using Flawless.Client.ViewModels;
-
-namespace Flawless.Client;
-
-public class ViewLocator : IDataTemplate
-{
- public Control? Build(object? param)
- {
- if (param is null)
- return null;
-
- var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
- 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;
- }
-}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/LoginViewModel.cs b/Flawless.Client/ViewModels/LoginViewModel.cs
index c064f5d..cbcdba7 100644
--- a/Flawless.Client/ViewModels/LoginViewModel.cs
+++ b/Flawless.Client/ViewModels/LoginViewModel.cs
@@ -1,64 +1,56 @@
using System;
using System.Reactive;
+using System.Reactive.Linq;
using System.Threading.Tasks;
using Flawless.Client.Remote;
+using Flawless.Client.Service;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using Refit;
namespace Flawless.Client.ViewModels;
-public partial class LoginViewModel : UserControlViewModelBase
+public partial class LoginViewModel : ViewModelBase, IRoutableViewModel
{
+
+ public string? UrlPathSegment { get; } = Guid.NewGuid().ToString();
+
+ public IScreen HostScreen { get; }
+
[Reactive] private string _username = String.Empty;
[Reactive] private string _password = String.Empty;
- [Reactive] private string _issue = String.Empty;
+ [Reactive(SetModifier = AccessModifier.Protected)] private string _issue = String.Empty;
- private MainWindowViewModel _main;
+ public IObservable CanLogin;
+
+ public IObservable CanRegister => Api.Current.Status.Select(s => s != null && s.AllowPublicRegister);
- public ReactiveCommand LoginCommand { get; }
-
- public ReactiveCommand RegisterCommand { get; }
-
- public ReactiveCommand ChooseServerCommand { get; }
-
- public LoginViewModel(MainWindowViewModel main)
+ public LoginViewModel(IScreen hostScreen)
{
- _main = main;
- Title = $"Login into '{ApiHelper.ServerUrl}'";
+ HostScreen = hostScreen;
- var canLogin = this.WhenAnyValue(
+ CanLogin = this.WhenAnyValue(
x => x.Username,
x => x.Password,
(user, pass) => !string.IsNullOrEmpty(user) && user.Length > 3 && !string.IsNullOrEmpty(pass) && pass.Length >= 6
);
- LoginCommand = ReactiveCommand.CreateFromTask(OnLoginAsync, canLogin);
- RegisterCommand = ReactiveCommand.Create(OnRegister);
- ChooseServerCommand = ReactiveCommand.Create(OnChooseServer);
}
-
- private void OnChooseServer()
+
+ [ReactiveCommand(CanExecute = nameof(CanRegister))]
+ private void Register()
{
- _main.RedirectToServerSetup();
+ HostScreen.Router.Navigate.Execute(new RegisterViewModel(HostScreen));
}
- private void OnRegister()
- {
- throw new NotImplementedException();
- }
-
- private async Task OnLoginAsync()
+ [ReactiveCommand(CanExecute = nameof(CanLogin))]
+ private async Task LoginAsync()
{
try
{
- ApiHelper.Token = await ApiHelper.Gateway.Login(new LoginRequest
- {
- Username = _username,
- Password = _password
- });
+ await Api.Current.LoginAsync(Username, Password);
}
catch (ApiException ex)
{
@@ -73,4 +65,5 @@ public partial class LoginViewModel : UserControlViewModelBase
Console.WriteLine($"Login as '{Username}' success!");
}
+
}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/MainWindowViewModel.cs b/Flawless.Client/ViewModels/MainWindowViewModel.cs
index fc43a40..0efb95d 100644
--- a/Flawless.Client/ViewModels/MainWindowViewModel.cs
+++ b/Flawless.Client/ViewModels/MainWindowViewModel.cs
@@ -1,25 +1,22 @@
-using ReactiveUI.SourceGenerators;
+using System.Reactive;
+using System.Reactive.Linq;
+using Flawless.Client.Service;
+using ReactiveUI;
+using ReactiveUI.SourceGenerators;
namespace Flawless.Client.ViewModels;
-public partial class MainWindowViewModel : ViewModelBase
+public partial class MainWindowViewModel : ViewModelBase, IScreen
{
- [Reactive(SetModifier = AccessModifier.Protected)]
- private UserControlViewModelBase _currentView;
-
+ public RoutingState Router { get; } = new RoutingState();
+
+ public ReactiveCommand GoBackCommand => Router.NavigateBack;
+
+ [Reactive] private bool _requireLogin = true;
+
public MainWindowViewModel()
{
- CurrentView = new ServerSetupViewModel(this);
- }
-
- public void RedirectToLogin()
- {
- CurrentView = new LoginViewModel(this);
- }
-
- public void RedirectToServerSetup()
- {
- CurrentView = new ServerSetupViewModel(this);
+ Api.Current.IsLoggedIn.Select(x => !x).BindTo(this, vm => vm.RequireLogin);
}
}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/RegisterViewModel.cs b/Flawless.Client/ViewModels/RegisterViewModel.cs
new file mode 100644
index 0000000..c04a208
--- /dev/null
+++ b/Flawless.Client/ViewModels/RegisterViewModel.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Reactive;
+using System.Threading.Tasks;
+using Avalonia;
+using Flawless.Client.Remote;
+using Flawless.Client.Service;
+using ReactiveUI;
+using ReactiveUI.SourceGenerators;
+using Refit;
+
+namespace Flawless.Client.ViewModels;
+
+public partial class RegisterViewModel : ViewModelBase, IRoutableViewModel
+{
+
+ public string? UrlPathSegment { get; } = Guid.NewGuid().ToString();
+
+ public IScreen HostScreen { get; }
+
+ [Reactive] private string _email;
+
+ [Reactive] private string _username;
+
+ [Reactive] private string _password;
+
+ [Reactive(SetModifier = AccessModifier.Protected)] private string _issue;
+
+ public RegisterViewModel(IScreen hostScreen)
+ {
+ HostScreen = hostScreen;
+ }
+
+
+ [ReactiveCommand]
+ private async Task RegisterAsync()
+ {
+ try
+ {
+ await Api.Current.Gateway.Register(new RegisterRequest
+ {
+ Email = _email,
+ Username = _username,
+ Password = _password
+ });
+
+
+ await Api.Current.LoginAsync(Username, Password);
+ }
+ catch (ApiException ex)
+ {
+ await Console.Error.WriteLineAsync($"Register as '{Username}' Failed: {ex.Content}");
+ Issue = ex.Content ?? String.Empty;
+ }
+ catch (Exception ex)
+ {
+ await Console.Error.WriteLineAsync($"Register as '{Username}' Failed: {ex}");
+ Issue = ex.Message;
+ }
+
+ Console.WriteLine($"Register as '{Username}' success!");
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/ServerConnectViewModel.cs b/Flawless.Client/ViewModels/ServerConnectViewModel.cs
new file mode 100644
index 0000000..7d7b707
--- /dev/null
+++ b/Flawless.Client/ViewModels/ServerConnectViewModel.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Reactive;
+using System.Reactive.Linq;
+using System.Reactive.Threading.Tasks;
+using System.Threading.Tasks;
+using Flawless.Client.Service;
+using ReactiveUI;
+using ReactiveUI.SourceGenerators;
+using Ursa.ReactiveUIExtension;
+
+namespace Flawless.Client.ViewModels;
+
+public partial class ServerConnectViewModel : ViewModelBase, IScreen
+{
+ public RoutingState Router { get; } = new RoutingState();
+
+ public ReactiveCommand GoBackCommand => Router.NavigateBack;
+
+ [Reactive]
+ private string _title = String.Empty;
+
+ [ReactiveCommand]
+ private async ValueTask OpenRepoPageAsync()
+ {
+ if (Api.Current.RequireRefreshToken()) await Router.NavigateAndReset.Execute(new ServerSetupViewModel(this)).ToTask();
+ }
+
+ public ServerConnectViewModel()
+ {
+ Router.CurrentViewModel
+ .Select(vm => vm?.GetType().Name.Replace("ViewModel", string.Empty) ?? "Hello")
+ .BindTo(this, vm => vm.Title);
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/ViewModels/ServerSetupViewModel.cs b/Flawless.Client/ViewModels/ServerSetupViewModel.cs
index 00dafea..f1d14e8 100644
--- a/Flawless.Client/ViewModels/ServerSetupViewModel.cs
+++ b/Flawless.Client/ViewModels/ServerSetupViewModel.cs
@@ -2,47 +2,45 @@
using System.Reactive;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using Flawless.Client.Service;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using Refit;
namespace Flawless.Client.ViewModels;
-public partial class ServerSetupViewModel : UserControlViewModelBase
+public partial class ServerSetupViewModel : ViewModelBase, IRoutableViewModel
{
+
+ public string? UrlPathSegment { get; } = Guid.NewGuid().ToString();
+
+ public IScreen HostScreen { get; }
+
[Reactive] private string _host = "http://localhost:5256/";
- [Reactive] private string? _issue;
+ [Reactive(SetModifier = AccessModifier.Protected)] private string? _issue;
- private MainWindowViewModel _main;
+ public IObservable CanSetHost { get; }
- public ReactiveCommand SetHostCommand { get; }
-
-
- private static readonly Regex httpRegex = new Regex(
- @"^(?i)https?://(([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{1,5})?(/[\w\-\.~%!$&'()*+,;=:@/?#]*)?(?-i)$",
- RegexOptions.Compiled | RegexOptions.CultureInvariant);
-
- public ServerSetupViewModel(MainWindowViewModel main)
+ public ServerSetupViewModel(IScreen hostScreen)
{
- _main = main;
- Title = "Connect to a Flawless Server";
+ HostScreen = hostScreen;
// Must clear this gateway
- if (ApiHelper.IsGatewayReady) ApiHelper.ClearGateway();
-
- SetHostCommand = ReactiveCommand.CreateFromTask(
- FetchServerDataAsync,
- this.WhenAnyValue(x => x.Host, s => !string.IsNullOrWhiteSpace(s)));
+ if (Api.Current.IsGatewayReady) Api.Current.ClearGateway();
+
+ CanSetHost = this.WhenAnyValue(x => x.Host, s => !string.IsNullOrWhiteSpace(s));
}
- private async Task FetchServerDataAsync()
+
+ [ReactiveCommand]
+ private async Task SetHostAsync()
{
try
{
Issue = string.Empty;
- await ApiHelper.SetGatewayAsync(Host);
- _main.RedirectToLogin();
+ await Api.Current.SetGatewayAsync(Host);
+ HostScreen.Router.Navigate.Execute(new LoginViewModel(HostScreen));
}
catch (ApiException ex)
{
diff --git a/Flawless.Client/ViewModels/ViewModelBase.cs b/Flawless.Client/ViewModels/ViewModelBase.cs
index d95bd26..229260c 100644
--- a/Flawless.Client/ViewModels/ViewModelBase.cs
+++ b/Flawless.Client/ViewModels/ViewModelBase.cs
@@ -1,15 +1,5 @@
-using Avalonia.Controls;
-using ReactiveUI;
-using ReactiveUI.SourceGenerators;
+using ReactiveUI;
namespace Flawless.Client.ViewModels;
-public abstract class ViewModelBase : ReactiveObject
-{
-}
-
-public abstract partial class UserControlViewModelBase : ViewModelBase
-{
- [Reactive(SetModifier = AccessModifier.Protected)]
- private string _title;
-}
+public abstract class ViewModelBase : ReactiveObject {}
diff --git a/Flawless.Client/Views/LoginView.axaml b/Flawless.Client/Views/LoginView.axaml
index e968f9d..70efd37 100644
--- a/Flawless.Client/Views/LoginView.axaml
+++ b/Flawless.Client/Views/LoginView.axaml
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:Flawless.Client.ViewModels"
- mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="400"
+ mc:Ignorable="d" d:DesignWidth="380" d:DesignHeight="540"
x:Class="Flawless.Client.Views.LoginView"
x:DataType="vm:LoginViewModel">
@@ -14,13 +14,11 @@
-
-
+
-
diff --git a/Flawless.Client/Views/LoginView.axaml.cs b/Flawless.Client/Views/LoginView.axaml.cs
index 0f07aba..fddf300 100644
--- a/Flawless.Client/Views/LoginView.axaml.cs
+++ b/Flawless.Client/Views/LoginView.axaml.cs
@@ -1,12 +1,18 @@
using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.ReactiveUI;
+using Flawless.Client.ViewModels;
+using ReactiveUI;
+using Ursa.ReactiveUIExtension;
namespace Flawless.Client.Views;
-public partial class LoginView : UserControl
+public partial class LoginView : ReactiveUrsaView
{
public LoginView()
{
InitializeComponent();
+ this.WhenActivated(disposables => { });
}
}
\ No newline at end of file
diff --git a/Flawless.Client/Views/MainView.axaml b/Flawless.Client/Views/MainView.axaml
new file mode 100644
index 0000000..9d5972e
--- /dev/null
+++ b/Flawless.Client/Views/MainView.axaml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/Flawless.Client/Views/MainView.axaml.cs b/Flawless.Client/Views/MainView.axaml.cs
new file mode 100644
index 0000000..1f10214
--- /dev/null
+++ b/Flawless.Client/Views/MainView.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace Flawless.Client.Views;
+
+public partial class MainView : UserControl
+{
+ public MainView()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/Views/MainWindowView.axaml b/Flawless.Client/Views/MainWindowView.axaml
index e5b1c9c..0312001 100644
--- a/Flawless.Client/Views/MainWindowView.axaml
+++ b/Flawless.Client/Views/MainWindowView.axaml
@@ -1,23 +1,26 @@
-
+ Title="Flawless Version Control"
+ mc:Ignorable="d" d:DesignWidth="1024" d:DesignHeight="768"
+ x:CompileBindings="True"
+ CanResize="True" MinWidth="800" MinHeight="600"
+ Icon="/Assets/avalonia-logo.ico">
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flawless.Client/Views/MainWindowView.axaml.cs b/Flawless.Client/Views/MainWindowView.axaml.cs
index 55d6f69..b9d7821 100644
--- a/Flawless.Client/Views/MainWindowView.axaml.cs
+++ b/Flawless.Client/Views/MainWindowView.axaml.cs
@@ -1,11 +1,16 @@
using Avalonia.Controls;
+using Avalonia.ReactiveUI;
+using Flawless.Client.ViewModels;
+using ReactiveUI;
+using Ursa.ReactiveUIExtension;
namespace Flawless.Client.Views;
-public partial class MainWindowView : Window
+public partial class MainWindowView : ReactiveUrsaWindow
{
public MainWindowView()
{
InitializeComponent();
+ this.WhenActivated(disposables => { });
}
}
\ No newline at end of file
diff --git a/Flawless.Client/Views/RegisterView.axaml b/Flawless.Client/Views/RegisterView.axaml
new file mode 100644
index 0000000..4127929
--- /dev/null
+++ b/Flawless.Client/Views/RegisterView.axaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Flawless.Client/Views/RegisterView.axaml.cs b/Flawless.Client/Views/RegisterView.axaml.cs
new file mode 100644
index 0000000..7f1a9b2
--- /dev/null
+++ b/Flawless.Client/Views/RegisterView.axaml.cs
@@ -0,0 +1,15 @@
+using Avalonia.ReactiveUI;
+using Flawless.Client.ViewModels;
+using ReactiveUI;
+using Ursa.ReactiveUIExtension;
+
+namespace Flawless.Client.Views;
+
+public partial class RegisterView : ReactiveUrsaView
+{
+ public RegisterView()
+ {
+ InitializeComponent();
+ this.WhenActivated(disposables => { });
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/Views/ServerConnectView.axaml b/Flawless.Client/Views/ServerConnectView.axaml
new file mode 100644
index 0000000..bef36d5
--- /dev/null
+++ b/Flawless.Client/Views/ServerConnectView.axaml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Flawless.Client/Views/ServerConnectView.axaml.cs b/Flawless.Client/Views/ServerConnectView.axaml.cs
new file mode 100644
index 0000000..8f942d1
--- /dev/null
+++ b/Flawless.Client/Views/ServerConnectView.axaml.cs
@@ -0,0 +1,15 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Flawless.Client.ViewModels;
+
+namespace Flawless.Client.Views;
+
+public partial class ServerConnectView : UserControl
+{
+ public ServerConnectView()
+ {
+ InitializeComponent();
+ DataContext = new ServerConnectViewModel();
+ }
+}
\ No newline at end of file
diff --git a/Flawless.Client/Views/ServerSetupView.axaml b/Flawless.Client/Views/ServerSetupView.axaml
index 139d952..97301a0 100644
--- a/Flawless.Client/Views/ServerSetupView.axaml
+++ b/Flawless.Client/Views/ServerSetupView.axaml
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Flawless.Client.ViewModels"
- mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="400"
+ mc:Ignorable="d" d:DesignWidth="380" d:DesignHeight="540"
x:Class="Flawless.Client.Views.ServerSetupView"
x:DataType="vm:ServerSetupViewModel">
@@ -14,7 +14,6 @@
-
diff --git a/Flawless.Client/Views/ServerSetupView.axaml.cs b/Flawless.Client/Views/ServerSetupView.axaml.cs
index 3135168..72c1dc0 100644
--- a/Flawless.Client/Views/ServerSetupView.axaml.cs
+++ b/Flawless.Client/Views/ServerSetupView.axaml.cs
@@ -1,13 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
+using Avalonia.ReactiveUI;
+using Flawless.Client.ViewModels;
+using ReactiveUI;
+using Ursa.ReactiveUIExtension;
namespace Flawless.Client.Views;
-public partial class ServerSetupView : UserControl
+public partial class ServerSetupView : ReactiveUrsaView
{
+
public ServerSetupView()
{
InitializeComponent();
+ this.WhenActivated(disposables => { });
}
}
\ No newline at end of file