diff --git a/.github/workflows/publish-web.yml b/.github/workflows/publish-web.yml
index 8e34846..1405b80 100644
--- a/.github/workflows/publish-web.yml
+++ b/.github/workflows/publish-web.yml
@@ -37,7 +37,9 @@ jobs:
run: >
dotnet publish ${{github.workspace}}/Client/UniScan.Client.App.Platform.Browser
-c Release
- -o ${{steps.strings.outputs.build-output-dir}}
+ -o ${{steps.strings.outputs.build-output-dir}}
+ /nr:false
+ /m:1
- name: Upload Artifact
uses: actions/upload-pages-artifact@v5
@@ -50,6 +52,7 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build-client-web
+ if: github.ref == 'refs/heads/main'
permissions:
id-token: write
pages: write
diff --git a/Client/Directory.Packages.props b/Client/Directory.Packages.props
index 529530b..a525dfe 100755
--- a/Client/Directory.Packages.props
+++ b/Client/Directory.Packages.props
@@ -1,44 +1,47 @@
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Client/UniScan.Client.App.Platform.Android/AndroidPaths.cs b/Client/UniScan.Client.App.Platform.Android/AndroidPaths.cs
index 51f2b1b..41424d6 100644
--- a/Client/UniScan.Client.App.Platform.Android/AndroidPaths.cs
+++ b/Client/UniScan.Client.App.Platform.Android/AndroidPaths.cs
@@ -10,4 +10,6 @@ public class AndroidPaths : IPlatformStandardPaths
public string DataPath => Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
public string ConfigPath => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+
+ public string CachePath => Path.Combine(DataPath, ".cache");
}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App.Platform.Android/AssemblyInfo.cs b/Client/UniScan.Client.App.Platform.Android/AssemblyInfo.cs
new file mode 100644
index 0000000..7d037e6
--- /dev/null
+++ b/Client/UniScan.Client.App.Platform.Android/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using UniScan.Client.App.Core.Platform;
+
+[assembly: UniScanPlatform]
\ No newline at end of file
diff --git a/Client/UniScan.Client.App.Platform.Android/UniScan.Client.App.Platform.Android.csproj b/Client/UniScan.Client.App.Platform.Android/UniScan.Client.App.Platform.Android.csproj
index 0a71920..b8ff1a5 100755
--- a/Client/UniScan.Client.App.Platform.Android/UniScan.Client.App.Platform.Android.csproj
+++ b/Client/UniScan.Client.App.Platform.Android/UniScan.Client.App.Platform.Android.csproj
@@ -9,10 +9,10 @@
1.0
apk
false
- UniScan
+ UniScanProject
UniScan Android
- 0.0.2
- 0.0.2
+ 0.0.3
+ 0.0.3
diff --git a/Client/UniScan.Client.App.Platform.Browser/AssemblyInfo.cs b/Client/UniScan.Client.App.Platform.Browser/AssemblyInfo.cs
new file mode 100644
index 0000000..7d037e6
--- /dev/null
+++ b/Client/UniScan.Client.App.Platform.Browser/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using UniScan.Client.App.Core.Platform;
+
+[assembly: UniScanPlatform]
\ No newline at end of file
diff --git a/Platform/UniScan.Platform.Implementations.Web/BrowserPaths.cs b/Client/UniScan.Client.App.Platform.Browser/BrowserPaths.cs
similarity index 54%
rename from Platform/UniScan.Platform.Implementations.Web/BrowserPaths.cs
rename to Client/UniScan.Client.App.Platform.Browser/BrowserPaths.cs
index 80bd5f3..8f37f09 100644
--- a/Platform/UniScan.Platform.Implementations.Web/BrowserPaths.cs
+++ b/Client/UniScan.Client.App.Platform.Browser/BrowserPaths.cs
@@ -1,7 +1,10 @@
-namespace UniScan.Platform.Implementations.Web;
+using UniScan.Platform;
+
+namespace UniScan.Client.App.Platform.Browser;
public class BrowserPaths : IPlatformStandardPaths
{
public string DataPath => "data";
public string ConfigPath => "config";
+ public string CachePath => "cache";
}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App.Platform.Browser/UniScan.Client.App.Platform.Browser.csproj b/Client/UniScan.Client.App.Platform.Browser/UniScan.Client.App.Platform.Browser.csproj
index b115f14..9253657 100755
--- a/Client/UniScan.Client.App.Platform.Browser/UniScan.Client.App.Platform.Browser.csproj
+++ b/Client/UniScan.Client.App.Platform.Browser/UniScan.Client.App.Platform.Browser.csproj
@@ -20,8 +20,8 @@
https://github.com/UniScanProject/UniScan
UniScanProject
UniScan Web
- 0.1.1
- 0.1.1
+ 0.1.2
+ 0.1.2
diff --git a/Client/UniScan.Client.App.Platform.Desktop/AssemblyInfo.cs b/Client/UniScan.Client.App.Platform.Desktop/AssemblyInfo.cs
new file mode 100644
index 0000000..7d037e6
--- /dev/null
+++ b/Client/UniScan.Client.App.Platform.Desktop/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using UniScan.Client.App.Core.Platform;
+
+[assembly: UniScanPlatform]
\ No newline at end of file
diff --git a/Client/UniScan.Client.App.Platform.Desktop/DesktopPaths.cs b/Client/UniScan.Client.App.Platform.Desktop/DesktopPaths.cs
index 11daee7..f1fa665 100644
--- a/Client/UniScan.Client.App.Platform.Desktop/DesktopPaths.cs
+++ b/Client/UniScan.Client.App.Platform.Desktop/DesktopPaths.cs
@@ -11,4 +11,8 @@ public class DesktopPaths : IPlatformStandardPaths
public string ConfigPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"UniScan");
+
+ public string CachePath => OperatingSystem.IsLinux() ?
+ Path.Combine(Environment.GetEnvironmentVariable("XDG_CACHE_HOME") ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cache"), "UniScan")
+ : Path.Combine(DataPath, "cache");
}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App.Platform.Desktop/UniScan.Client.App.Platform.Desktop.csproj b/Client/UniScan.Client.App.Platform.Desktop/UniScan.Client.App.Platform.Desktop.csproj
index 2313850..e0575f4 100755
--- a/Client/UniScan.Client.App.Platform.Desktop/UniScan.Client.App.Platform.Desktop.csproj
+++ b/Client/UniScan.Client.App.Platform.Desktop/UniScan.Client.App.Platform.Desktop.csproj
@@ -5,10 +5,10 @@
See https://docs.avaloniaui.net/docs/guides/platforms/platform-specific-code/dotnet for more details.-->
net10.0
enable
- UniScan
+ UniScanProject
UniScan Desktop
- 0.0.2
- 0.0.2
+ 0.0.3
+ 0.0.3
diff --git a/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.Initializers.cs b/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.Initializers.cs
deleted file mode 100644
index 0ed109f..0000000
--- a/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.Initializers.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
-using UniScan.Client.App.ViewModels;
-using UniScan.Client.App.Views;
-
-namespace UniScan.Client.App.Core.Initialization;
-
-public partial class UniScanAppInitializationPipeline
-{
- internal static async Task InitializeViews(TaskContexts.PostClient ctx)
- {
- ctx.Status.Value = "Initializing UI";
-
- ctx.ServiceCollection.AddSingleton();
- ctx.ServiceCollection.AddSingleton();
-
- ctx.ServiceCollection.AddSingleton();
- }
-
- internal static async Task InitializeServiceProvider(TaskContexts.PreServiceProvider ctx)
- {
- ctx.Status.Value = "Building ServiceProvider";
-
- ctx.Services = ctx.ServiceCollection.BuildServiceProvider();
- }
-
- internal static async Task InitializeRemotes(TaskContexts.PostServiceProvider ctx)
- {
- ctx.Status.Value = "Saving remotes";
-
- await ctx.Client!.RemoteManagerFile.SaveAsync(ctx.Client.RemoteManager);
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Pipeline/ITaskContext.cs b/Client/UniScan.Client.App/Core/Pipeline/ITaskContext.cs
deleted file mode 100644
index 137156f..0000000
--- a/Client/UniScan.Client.App/Core/Pipeline/ITaskContext.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using R3;
-
-namespace UniScan.Client.App.Core.Pipeline;
-
-public interface ITaskContext
-{
- public BindableReactiveProperty Status { get; }//todo why not give setter func to top level reactiveproperty???
-}
-
-public interface ITaskContext : ITaskContext
- where TSelf : ITaskContext
- where TOldContext : ITaskContext
-{
- static abstract TSelf TransitionFrom(TOldContext oldContext);
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Pipeline/ITaskStage.cs b/Client/UniScan.Client.App/Core/Pipeline/ITaskStage.cs
deleted file mode 100644
index 0b19f62..0000000
--- a/Client/UniScan.Client.App/Core/Pipeline/ITaskStage.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace UniScan.Client.App.Core.Pipeline;
-
-public interface ITaskStage
-{
- int Count { get; }
- IEnumerable> Tasks { get; }
-
- ITaskContext Transition(ITaskContext old);
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.Initializers.cs b/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.Initializers.cs
new file mode 100644
index 0000000..78e2c06
--- /dev/null
+++ b/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.Initializers.cs
@@ -0,0 +1,50 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using UniScan.Client.App.Views;
+using UniScan.Client.App.Views.Settings;
+using UniScan.Client.Core.Remote;
+using UniScan.Network;
+using UniScan.Network.Registry.Source.Sources;
+using MainViewModel = UniScan.Client.App.Views.MainViewModel;
+
+namespace UniScan.Client.App.Core.Pipeline.Initialization;
+
+public partial class UniScanAppInitializationPipeline
+{
+ internal static async Task InitializeViews(TaskContexts.PostClient ctx, CancellationToken ct = default)
+ {
+ ctx.Status.Value = "Initializing UI";
+
+ ctx.ServiceCollection.AddSingleton();
+ ctx.ServiceCollection.AddSingleton();
+
+ ctx.ServiceCollection.AddSingleton();
+ }
+
+ internal static async Task InitializeServiceProvider(TaskContexts.PreServiceProvider ctx, CancellationToken ct = default)
+ {
+ ctx.Status.Value = "Building ServiceProvider";
+
+ ctx.Services = ctx.ServiceCollection.BuildServiceProvider();
+ }
+
+ internal static async Task InitializeRemotes(TaskContexts.PostServiceProvider ctx, CancellationToken ct = default)
+ {
+ ctx.Status.Value = "Loading remotes";
+
+ IRemoteStorage remoteStorage = ctx.Services.GetRequiredService();
+ await remoteStorage.LoadAsync();
+ }
+
+ internal Task RegisterPackets(UniScanAppInitializationPipeline.TaskContexts.PostServiceProvider ctx,
+ CancellationToken ct = default)
+ {
+ ctx.Status.Value = "Registering packets";
+
+ PacketRegistry registry = ctx.Services.GetRequiredService();
+ registry.RegisterFromSource();
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.TaskContexts.cs b/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.TaskContexts.cs
similarity index 70%
rename from Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.TaskContexts.cs
rename to Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.TaskContexts.cs
index a0e8d60..a6d43ea 100644
--- a/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.TaskContexts.cs
+++ b/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.TaskContexts.cs
@@ -1,10 +1,10 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using R3;
-using UniScan.Client.App.Core.Pipeline;
+using Shiki.TaskPipeline;
using UniScan.Client.Core;
-namespace UniScan.Client.App.Core.Initialization;
+namespace UniScan.Client.App.Core.Pipeline.Initialization;
public partial class UniScanAppInitializationPipeline
{
@@ -22,9 +22,7 @@ public class PreClient(string status, ServiceCollection serviceCollection) : ITa
public BindableReactiveProperty Status { get; } = new(status);
public ServiceCollection ServiceCollection { get; } = serviceCollection;
-
- public UniScanClient? Client { get; set; } = null;
-
+
public PreClient(Early ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollection)
{
}
@@ -34,18 +32,14 @@ public PreClient(Early ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollectio
public class PostClient(
string status,
- ServiceCollection serviceCollection,
- UniScanClient client)
+ ServiceCollection serviceCollection)
: ITaskContext
{
public BindableReactiveProperty Status { get; } = new(status);
public ServiceCollection ServiceCollection { get; } = serviceCollection;
-
- public UniScanClient Client { get; } = client;
-
- public PostClient(PreClient ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollection,
- ctx.Client ?? throw new NullReferenceException())
+
+ public PostClient(PreClient ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollection)
{
}
@@ -54,20 +48,16 @@ public PostClient(PreClient ctx) : this(ctx.Status.CurrentValue, ctx.ServiceColl
public class PreServiceProvider(
string status,
- ServiceCollection serviceCollection,
- UniScanClient client)
+ ServiceCollection serviceCollection)
: ITaskContext
{
public BindableReactiveProperty Status { get; } = new(status);
public ServiceCollection ServiceCollection { get; } = serviceCollection;
-
- public UniScanClient Client { get; } = client;
-
+
public IServiceProvider? Services { get; set; } = null;
- public PreServiceProvider(PostClient ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollection,
- ctx.Client ?? throw new NullReferenceException())
+ public PreServiceProvider(PostClient ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollection)
{
}
@@ -76,21 +66,14 @@ public PreServiceProvider(PostClient ctx) : this(ctx.Status.CurrentValue, ctx.Se
public class PostServiceProvider(
string status,
- ServiceCollection serviceCollection,
- UniScanClient client,
IServiceProvider provider)
: ITaskContext
{
public BindableReactiveProperty Status { get; } = new(status);
-
- public ServiceCollection ServiceCollection { get; } = serviceCollection;
-
- public UniScanClient Client { get; } = client;
-
+
public IServiceProvider Services { get; } = provider;
- public PostServiceProvider(PreServiceProvider ctx) : this(ctx.Status.CurrentValue, ctx.ServiceCollection,
- ctx.Client ?? throw new NullReferenceException(),
+ public PostServiceProvider(PreServiceProvider ctx) : this(ctx.Status.CurrentValue,
ctx.Services ??
throw new NullReferenceException())
{
diff --git a/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.cs b/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.cs
similarity index 88%
rename from Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.cs
rename to Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.cs
index d4c3d52..c541e75 100644
--- a/Client/UniScan.Client.App/Core/Initialization/UniScanAppInitializationPipeline.cs
+++ b/Client/UniScan.Client.App/Core/Pipeline/Initialization/UniScanAppInitializationPipeline.cs
@@ -2,9 +2,9 @@
using System.Threading.Tasks;
using R3;
using Serilog;
-using UniScan.Client.App.Core.Pipeline;
+using Shiki.TaskPipeline;
-namespace UniScan.Client.App.Core.Initialization;
+namespace UniScan.Client.App.Core.Pipeline.Initialization;
public partial class UniScanAppInitializationPipeline
{
@@ -17,7 +17,7 @@ public UniScanAppInitializationPipeline(UniScanApp app)
Pipeline = new TaskPipelineBuilder()
//early
.ThenRun(app.InitializeEnvironment)
- .ThenRun(_ =>
+ .ThenRun((_, _) =>
{
_logger = Log.ForContext();
@@ -33,8 +33,9 @@ public UniScanAppInitializationPipeline(UniScanApp app)
.ThenRun(InitializeServiceProvider)
.ThenTransitionTo()
.ThenRun(InitializeRemotes)
+ .ThenRun(RegisterPackets)
.ThenRun(app.FinishInitialization)
- .ThenRun(_ =>
+ .ThenRun((_, _) =>
{
_subscription?.Dispose();
diff --git a/Client/UniScan.Client.App/Core/Pipeline/TaskPipeline.cs b/Client/UniScan.Client.App/Core/Pipeline/TaskPipeline.cs
deleted file mode 100644
index 6af65b6..0000000
--- a/Client/UniScan.Client.App/Core/Pipeline/TaskPipeline.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using R3;
-
-namespace UniScan.Client.App.Core.Pipeline;
-
-public class TaskPipeline
-{
- public BindableReactiveProperty Progress { get; } = new(0.0);
- public BindableReactiveProperty Status { get; } = new("Starting");
-
- private readonly List _stages = [];
-
- internal TaskPipeline() {}//only allow builder to call ctor
-
- internal void Add(ITaskStage stage) => _stages.Add(stage);
-
- public async Task RunAsync(ITaskContext initial)
- {
- ITaskContext currentContext = initial;
- IDisposable? subscription = null;
-
- int tasks = _stages.Sum(s => s.Count);
- int completed = 0;
- try
- {
- foreach (ITaskStage stage in _stages)
- {
- currentContext = stage.Transition(currentContext);
-
- subscription?.Dispose(); //make sure old is disposed otherwise we will leak subscriptions
- //todo see comment in itaskcontext
- subscription = currentContext.Status.Subscribe(s => Status.Value = s);
-
- foreach (var task in stage.Tasks)
- {
- await task(currentContext);
-
- completed++;
- Progress.Value = (completed * 100) / tasks;
- }
- }
- }//todo catch exception? idk how to get this fucking exception to bubble
- finally
- {
- subscription?.Dispose();
- }
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Pipeline/TaskPipelineBuilder.cs b/Client/UniScan.Client.App/Core/Pipeline/TaskPipelineBuilder.cs
deleted file mode 100644
index 5d1c6df..0000000
--- a/Client/UniScan.Client.App/Core/Pipeline/TaskPipelineBuilder.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using System.Threading.Tasks;
-
-namespace UniScan.Client.App.Core.Pipeline;
-
-public class TaskPipelineBuilder
- where TContext : class, ITaskContext
-{
- private readonly TaskPipeline _pipeline;
- private readonly TaskStage _stage;
-
- public TaskPipelineBuilder()
- {
- _pipeline = new TaskPipeline();
- _stage = new TaskStage(ctx => (TContext)ctx);
-
- _pipeline.Add(_stage);
- }
-
- public TaskPipelineBuilder(TaskPipeline pipeline, TaskStage stage)
- {
- _pipeline = pipeline;
- _stage = stage;
-
- _pipeline.Add(_stage);
- }
-
- public TaskPipelineBuilder ThenRun(Func task)
- {
- _stage.Add(task);
- return this;
- }
-
- //idk better word than transition im too sleepy
- public TaskPipelineBuilder ThenTransitionTo(Func transition)
- where TNewContext : class, ITaskContext
- => new(_pipeline, new TaskStage(ctx => transition((TContext)ctx)));
-
- public TaskPipelineBuilder ThenTransitionTo()
- where TNewContext : class, ITaskContext
- => new(_pipeline, new TaskStage(ctx => TNewContext.TransitionFrom((TContext)ctx)));
-
- public TaskPipeline Build() => _pipeline;
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Pipeline/TaskStage.cs b/Client/UniScan.Client.App/Core/Pipeline/TaskStage.cs
deleted file mode 100644
index d7bbd21..0000000
--- a/Client/UniScan.Client.App/Core/Pipeline/TaskStage.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace UniScan.Client.App.Core.Pipeline;
-
-public class TaskStage : ITaskStage
- where TOldContext : class, ITaskContext
- where TContext : class, ITaskContext
-{
- private readonly Func _transition;
- private readonly List> _tasks = [];
-
- public int Count => _tasks.Count;
-
- public IEnumerable> Tasks
- {
- get
- {
- foreach (var task in _tasks)
- yield return ctx => task((TContext)ctx);
- }
- }
-
- public TaskStage(Func transition)
- {
- _transition = transition;
- }
-
- public void Add(Func task) => _tasks.Add(task);
- public ITaskContext Transition(ITaskContext old) => old is not TOldContext ctx
- ? throw new InvalidCastException()
- : _transition(ctx);
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Core/Platform/UniScanPlatformAttribute.cs b/Client/UniScan.Client.App/Core/Platform/UniScanPlatformAttribute.cs
new file mode 100644
index 0000000..d57d79d
--- /dev/null
+++ b/Client/UniScan.Client.App/Core/Platform/UniScanPlatformAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace UniScan.Client.App.Core.Platform;
+
+//hack to get correct platform assembly
+//without this, android breaks
+[AttributeUsage(AttributeTargets.Assembly)]
+public class UniScanPlatformAttribute : Attribute;
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/UI/ConnectionMethod/IConnectionMethodFactoryViewModel.cs b/Client/UniScan.Client.App/UI/ConnectionMethod/IConnectionMethodFactoryViewModel.cs
index b438195..777b643 100644
--- a/Client/UniScan.Client.App/UI/ConnectionMethod/IConnectionMethodFactoryViewModel.cs
+++ b/Client/UniScan.Client.App/UI/ConnectionMethod/IConnectionMethodFactoryViewModel.cs
@@ -1,4 +1,4 @@
-using UniScan.Client.App.ViewModels;
+using UniScan.Client.App.Views.ViewModel;
using UniScan.Network.Client.Remote.Connection;
namespace UniScan.Client.App.UI.ConnectionMethod;
diff --git a/Client/UniScan.Client.App/UI/Util/RelativeUnitConverter.cs b/Client/UniScan.Client.App/UI/Conversion/RelativeUnitConverter.cs
similarity index 96%
rename from Client/UniScan.Client.App/UI/Util/RelativeUnitConverter.cs
rename to Client/UniScan.Client.App/UI/Conversion/RelativeUnitConverter.cs
index 537504e..3c25c59 100644
--- a/Client/UniScan.Client.App/UI/Util/RelativeUnitConverter.cs
+++ b/Client/UniScan.Client.App/UI/Conversion/RelativeUnitConverter.cs
@@ -4,7 +4,7 @@
using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml;
-namespace UniScan.Client.App.UI.Util;
+namespace UniScan.Client.App.UI.Conversion;
public class RelativeUnitConverter : MarkupExtension, IValueConverter
{
diff --git a/Client/UniScan.Client.App/UI/ViewLocator.cs b/Client/UniScan.Client.App/UI/ViewLocator.cs
index 2c27c69..78ddbdb 100755
--- a/Client/UniScan.Client.App/UI/ViewLocator.cs
+++ b/Client/UniScan.Client.App/UI/ViewLocator.cs
@@ -2,7 +2,7 @@
using System.Diagnostics.CodeAnalysis;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
-using UniScan.Client.App.ViewModels;
+using UniScan.Client.App.Views.ViewModel;
namespace UniScan.Client.App.UI;
diff --git a/Client/UniScan.Client.App/UniScan.Client.App.csproj b/Client/UniScan.Client.App/UniScan.Client.App.csproj
index a8352e0..9980328 100755
--- a/Client/UniScan.Client.App/UniScan.Client.App.csproj
+++ b/Client/UniScan.Client.App/UniScan.Client.App.csproj
@@ -5,8 +5,8 @@
14
true
UniScanProject
- 0.0.9
- 0.0.9
+ 0.1.0
+ 0.1.0
@@ -14,7 +14,9 @@
+
+
@@ -44,14 +46,128 @@
-
+
+ RemoteInfoView.axaml
+ Code
+
+
+ RemoteLinkControl.axaml
+ Code
+
+
+ SidebarRemoteItemView.axaml
+ Code
+
+
+ DeviceInfoView.axaml
+ Code
+
+
+ DeviceListView.axaml
+ Code
+
+
+ DeviceSidebarView.axaml
+ Code
+
+
MainRemotePageView.axaml
Code
-
+
+ RemoteView.axaml
+ Code
+
+
+ NotConnectedRemotePageView.axaml
+ Code
+
+
+ TCPConnectionMethodFactoryView.axaml
+ Code
+
+
+ MainPageView.axaml
+ Code
+
+
DisconnectedRemotePageView.axaml
Code
+
+ HeadedSeparatorControl.axaml
+ Code
+
+
+ ClientSettingsView.axaml
+ Code
+
+
+ LoadingView.axaml
+ Code
+
+
+ EmptyPageView.axaml
+ Code
+
+
+ AddRemoteDialog.axaml
+ Code
+
+
+ HeadedSeparatorControl.axaml
+
+
+ LoadingView.axaml
+
+
+ EmptyPageView.axaml
+
+
+ HomePageView.axaml
+
+
+ AddRemoteDialog.axaml
+
+
+ TCPConnectionMethodFactoryView.axaml
+
+
+ DisconnectedRemotePageView.axaml
+
+
+ NotConnectedRemotePageView.axaml
+
+
+ DeviceInfoControl.axaml
+
+
+ DeviceListControl.axaml
+
+
+ RemotePageView.axaml
+
+
+ RemoteInfoControl.axaml
+
+
+ RemoteLinkControl.axaml
+
+
+ SidebarRemoteItemControl.axaml
+
+
+ RemoteRootPageView.axaml
+
+
+ MainView.axaml
+
+
+ RootView.axaml
+
+
+ ClientSettingsView.axaml
+
@@ -83,9 +199,10 @@
-
-
+
+
+
-
+
diff --git a/Client/UniScan.Client.App/UniScanApp.Initializers.cs b/Client/UniScan.Client.App/UniScanApp.Initializers.cs
index f2dda92..8f71ce3 100644
--- a/Client/UniScan.Client.App/UniScanApp.Initializers.cs
+++ b/Client/UniScan.Client.App/UniScanApp.Initializers.cs
@@ -1,22 +1,27 @@
using System;
using System.IO;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Serilog;
using Shiki.ModuleManagement;
using Shiki.ModuleManagement.Implementations.Sources;
-using UniScan.Client.App.Core.Initialization;
using UniScan.Client.App.Core.Module;
using UniScan.Client.App.Core.Module.Modules.Internal;
+using UniScan.Client.App.Core.Pipeline.Initialization;
using UniScan.Client.Core;
using UniScan.Client.Core.DI.Factory;
+using UniScan.Client.Core.Remote;
+using UniScan.Network;
+using UniScan.Network.Registry.Source.Sources;
using UniScan.Platform.DependencyInjection;
namespace UniScan.Client.App;
public partial class UniScanApp
{
- internal async Task InitializeEnvironment(UniScanAppInitializationPipeline.TaskContexts.Early context)
+ internal async Task InitializeEnvironment(UniScanAppInitializationPipeline.TaskContexts.Early context, CancellationToken ct = default)
{
context.Status.Value = "Initializing environment";
@@ -33,10 +38,16 @@ internal async Task InitializeEnvironment(UniScanAppInitializationPipeline.TaskC
.ForContext();
_hostEnvironment.AddToDi(context.ServiceCollection);
- Log.Logger.Debug("Initialized Environment {Env}", _hostEnvironment);
+
+ context.ServiceCollection.AddLogging(builder =>
+ {
+ builder.ClearProviders();
+ builder.AddSerilog();
+ });
+ Log.Debug("Initialized Environment {Env}", _hostEnvironment);
}
- internal async Task InitializeSoftwareInfo(UniScanAppInitializationPipeline.TaskContexts.Early ctx)
+ internal async Task InitializeSoftwareInfo(UniScanAppInitializationPipeline.TaskContexts.Early ctx, CancellationToken ct = default)
{
ctx.Status.Value = "Initializing SoftwareInfo";
@@ -44,7 +55,7 @@ internal async Task InitializeSoftwareInfo(UniScanAppInitializationPipeline.Task
Log.Information("{Info}", SoftwareInfo);
}
- internal async Task InitializeModules(UniScanAppInitializationPipeline.TaskContexts.Early ctx)
+ internal async Task InitializeModules(UniScanAppInitializationPipeline.TaskContexts.Early ctx, CancellationToken ct = default)
{
ctx.Status.Value = "Initializing modules";
@@ -72,19 +83,17 @@ internal async Task InitializeModules(UniScanAppInitializationPipeline.TaskConte
foreach (IUniScanClientAppModule module in ModuleStorage.Modules)
{
module.ConfigureDi(ctx.ServiceCollection);
+ ctx.ServiceCollection.AddSingleton(module);
}
}
- internal async Task InitializeClient(UniScanAppInitializationPipeline.TaskContexts.PreClient ctx)
+ internal async Task InitializeClient(UniScanAppInitializationPipeline.TaskContexts.PreClient ctx, CancellationToken ct = default)
{
- ctx.Status.Value = "Initializing client and loading remotes";
-
- ctx.Client = await UniScanClient.CreateInstanceAsync(_hostEnvironment, SoftwareInfo);
- ctx.ServiceCollection.AddSingleton(ctx.Client);
- ctx.ServiceCollection.AddSingleton(_ => ctx.Client.ServiceProvider.GetRequiredService());
+ ctx.Status.Value = "Initializing client";
+ ctx.ServiceCollection.AddUniScanClient(_hostEnvironment, SoftwareInfo);
}
- internal Task FinishInitialization(UniScanAppInitializationPipeline.TaskContexts.PostServiceProvider ctx)
+ internal Task FinishInitialization(UniScanAppInitializationPipeline.TaskContexts.PostServiceProvider ctx, CancellationToken ct = default)
{
try
{
diff --git a/Client/UniScan.Client.App/UniScanApp.axaml b/Client/UniScan.Client.App/UniScanApp.axaml
index 8be1ca7..374ea27 100755
--- a/Client/UniScan.Client.App/UniScanApp.axaml
+++ b/Client/UniScan.Client.App/UniScanApp.axaml
@@ -1,14 +1,10 @@
@@ -17,7 +13,7 @@
-
+
diff --git a/Client/UniScan.Client.App/UniScanApp.axaml.cs b/Client/UniScan.Client.App/UniScanApp.axaml.cs
index ca522f5..06f1930 100755
--- a/Client/UniScan.Client.App/UniScanApp.axaml.cs
+++ b/Client/UniScan.Client.App/UniScanApp.axaml.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
@@ -14,9 +15,10 @@
using Shiki.Common.Identity;
using Shiki.ModuleManagement;
using Shiki.ModuleManagement.Implementations.Sources;
-using UniScan.Client.App.Core.Initialization;
using UniScan.Client.App.Core.Module;
-using UniScan.Client.App.ViewModels;
+using UniScan.Client.App.Core.Pipeline.Initialization;
+using UniScan.Client.App.Core.Platform;
+using UniScan.Client.App.Views.Global;
using UniScan.Client.Core;
using UniScan.Client.Core.DI.Factory;
using UniScan.Client.Core.Module.Modules.Internal;
@@ -25,10 +27,10 @@
using UniScan.Platform;
using UniScan.Platform.DependencyInjection;
using MainView = UniScan.Client.App.Views.MainView;
-using MainViewModel = UniScan.Client.App.ViewModels.MainViewModel;
+using MainViewModel = UniScan.Client.App.Views.MainViewModel;
using MainWindow = UniScan.Client.App.Views.MainWindow;
using RootView = UniScan.Client.App.Views.RootView;
-using RootViewModel = UniScan.Client.App.ViewModels.RootViewModel;
+using RootViewModel = UniScan.Client.App.Views.RootViewModel;
namespace UniScan.Client.App;
@@ -43,8 +45,10 @@ public partial class UniScanApp : Application
private HostEnvironment _hostEnvironment = null!;
+ private static readonly Assembly PlatformAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.IsDefined(typeof(UniScanPlatformAttribute))) ?? typeof(UniScanApp).Assembly;
+
public static readonly Identifier Identifier = UniScanClient.ClientIdentifier.Derived("app");
- public static readonly SemVersion PlatformVersion = SemVersion.Parse(Assembly.GetEntryAssembly()!.InformationalVersionString);
+ public static readonly SemVersion PlatformVersion = SemVersion.Parse(PlatformAssembly.InformationalVersionString);
public static readonly ClientSoftwareInfo SoftwareInfo = new(
Identifier,
@@ -75,7 +79,7 @@ public override void OnFrameworkInitializationCompleted()
{
Log.Information("Loading root view");
- RootViewModel = new RootViewModel(new LoadingViewModel(InitializationPipeline.Pipeline));
+ RootViewModel = new RootViewModel(new LoadingViewModel("Loading...", InitializationPipeline.Pipeline));
switch (ApplicationLifetime)
{
case IClassicDesktopStyleApplicationLifetime desktop:
diff --git a/Client/UniScan.Client.App/ViewModels/ClientSettingsViewModel.cs b/Client/UniScan.Client.App/ViewModels/ClientSettingsViewModel.cs
deleted file mode 100644
index 106d0a2..0000000
--- a/Client/UniScan.Client.App/ViewModels/ClientSettingsViewModel.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace UniScan.Client.App.ViewModels;
-
-public class ClientSettingsViewModel : ViewModelBase
-{
-
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Controls/DeviceInfoViewModel.cs b/Client/UniScan.Client.App/ViewModels/Controls/DeviceInfoViewModel.cs
deleted file mode 100644
index b23239f..0000000
--- a/Client/UniScan.Client.App/ViewModels/Controls/DeviceInfoViewModel.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using UniScan.Client.Core.Config.Types;
-using UniScan.Network.Data;
-
-namespace UniScan.Client.App.ViewModels.Controls;
-
-public class DeviceInfoViewModel(DeviceDto info, RemoteServer parentRemote) : ViewModelBase
-{
- public DeviceDto Info { get; } = info;
- public RemoteServer ParentRemote { get; } = parentRemote;
-
- public bool HasModelInfo => Info.Specs != null;
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Controls/DeviceListViewModel.cs b/Client/UniScan.Client.App/ViewModels/Controls/DeviceListViewModel.cs
deleted file mode 100644
index f75925a..0000000
--- a/Client/UniScan.Client.App/ViewModels/Controls/DeviceListViewModel.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using ObservableCollections;
-using UniScan.Client.Core.Config.Types;
-
-namespace UniScan.Client.App.ViewModels.Controls;
-
-public class DeviceListViewModel(RemoteServer server) : ViewModelBase, IDisposable
-{
- public INotifyCollectionChangedSynchronizedViewList DevicesView { get; } = server.Devices.CreateView(kvp => new DeviceInfoViewModel(kvp.Value, server)).ToNotifyCollectionChanged(SynchronizationContextCollectionEventDispatcher.Current);
-
- public void Dispose()
- {
- DevicesView.Dispose();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Controls/HeadedSeparatorControlModel.cs b/Client/UniScan.Client.App/ViewModels/Controls/HeadedSeparatorControlModel.cs
deleted file mode 100644
index 18ec103..0000000
--- a/Client/UniScan.Client.App/ViewModels/Controls/HeadedSeparatorControlModel.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.ViewModels.Controls;
-
-public class HeadedSeparatorControlModel : UserControl
-{
-
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Controls/RemoteControlViewModel.cs b/Client/UniScan.Client.App/ViewModels/Controls/RemoteControlViewModel.cs
deleted file mode 100644
index 47dadd4..0000000
--- a/Client/UniScan.Client.App/ViewModels/Controls/RemoteControlViewModel.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using CommunityToolkit.Mvvm.Input;
-using CommunityToolkit.Mvvm.Messaging;
-using UniScan.Client.Core.Config.Types;
-
-namespace UniScan.Client.App.ViewModels.Controls;
-
-public partial class RemoteControlViewModel : ViewModelBase, IDisposable
-{
- public RemoteServer Remote { get; }
-
- private readonly RemoteViewModel _viewModel;
-
- public RemoteControlViewModel(RemoteServer remote)
- {
- this.Remote = remote;
-
- _viewModel = new RemoteViewModel(Remote);
- }
-
- [RelayCommand]
- public async Task OnClicked()
- {
- WeakReferenceMessenger.Default.Send(new NavigationMessage(_viewModel), MainViewModel.Identifier);
- }
-
- [RelayCommand]
- public async Task OnConnectClicked()
- {
-
- }
-
- public void Dispose()
- {
- _viewModel.Dispose();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Pages/EmptyPageViewModel.cs b/Client/UniScan.Client.App/ViewModels/Pages/EmptyPageViewModel.cs
deleted file mode 100644
index 0bcec94..0000000
--- a/Client/UniScan.Client.App/ViewModels/Pages/EmptyPageViewModel.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace UniScan.Client.App.ViewModels.Pages;
-
-public class EmptyPageViewModel : ViewModelBase
-{
-
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Pages/MainRemotePageViewModel.cs b/Client/UniScan.Client.App/ViewModels/Pages/MainRemotePageViewModel.cs
deleted file mode 100644
index 104b9b3..0000000
--- a/Client/UniScan.Client.App/ViewModels/Pages/MainRemotePageViewModel.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using UniScan.Client.App.ViewModels.Controls;
-using UniScan.Client.Core.Config.Types;
-
-namespace UniScan.Client.App.ViewModels.Pages;
-
-public partial class MainRemotePageViewModel(RemoteServer remote, DeviceListViewModel deviceList) : ViewModelBase
-{
- public RemoteServer Remote { get; set; } = remote;
-
- public DeviceListViewModel DeviceList { get; } = deviceList;
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Pages/NotConnectedRemotePageViewModel.cs b/Client/UniScan.Client.App/ViewModels/Pages/NotConnectedRemotePageViewModel.cs
deleted file mode 100644
index 5fb6ee7..0000000
--- a/Client/UniScan.Client.App/ViewModels/Pages/NotConnectedRemotePageViewModel.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using CommunityToolkit.Mvvm.Input;
-using Serilog;
-using UniScan.Client.Core.Config.Types;
-
-namespace UniScan.Client.App.ViewModels.Pages;
-
-public partial class NotConnectedRemotePageViewModel(RemoteServer remote) : ViewModelBase
-{
- public RemoteServer Remote { get; set; } = remote;
-
- public bool HasConnectionMethod { get; set; } = remote.ConnectionMethod != null;
-
- [RelayCommand]
- public async Task OnAnonymousConnectClicked()
- {
- if (Remote.Socket.Connected)
- return;
-
- try
- {
- await Remote.Socket.StartAsync();
-
- if (Remote.Socket.Connected)
- {
- _ = Remote.RunConnectionAsync();
- }
- else
- {
- Log.Error("Failed to connect!");
- }
- }
- catch (Exception ex)
- {
- Log.Information(ex, "FUCK!");
- }
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/RemoteViewModel.cs b/Client/UniScan.Client.App/ViewModels/RemoteViewModel.cs
deleted file mode 100644
index ddaf31c..0000000
--- a/Client/UniScan.Client.App/ViewModels/RemoteViewModel.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-using System;
-using Avalonia.Threading;
-using CommunityToolkit.Mvvm.Input;
-using Shiki.Common.Identity;
-using Shiki.Common.Identity.Slug;
-using Shiki.Common.Identity.Slug.Formatting.Formatters;
-using UniScan.Client.App.ViewModels.Controls;
-using UniScan.Client.App.ViewModels.Pages;
-using UniScan.Client.Core;
-using UniScan.Client.Core.Config.Types;
-using UniScan.Network.Util;
-
-namespace UniScan.Client.App.ViewModels;
-
-public class RemoteViewModel : SubPagedViewModelBase, IDisposable
-{
- public RemoteServer Remote { get; set; }
-
- private readonly NotConnectedRemotePageViewModel _notConnectedPage;
- private MainRemotePageViewModel? _mainPage;
-
- public DeviceListViewModel DeviceList { get; }
-
- public RemoteViewModel(RemoteServer remote) : base(new NotConnectedRemotePageViewModel(remote), UniScanApp.Identifier.Derived("view_model", "remote", new Slug(remote.DisplayName ?? Guid.NewGuid().ToString())))
- {
- this._notConnectedPage = (NotConnectedRemotePageViewModel)CurrentSubpage;
- this.Remote = remote;
-
- DeviceList = new DeviceListViewModel(remote);
-
- this.Remote.Socket.ConnectionState.Disconnected += OnDisconnected;
- this.Remote.Socket.ConnectionState.Connected += OnConnected;
- }
-
- private void OnDisconnected(object? sender, ConnectionStateTracker.ConnectionStateChangedEventArgs eventArgs)
- {
- Dispatcher.UIThread.Post(() =>
- {
- string reason = "Unknown reason, maybe there is more info in the logs.";
- if (eventArgs.Channel.HasAttribute(ServerAttributes.DisconnectReasonAttribute))
- {
- reason = eventArgs.Channel.GetAttribute(ServerAttributes.DisconnectReasonAttribute).Get();
- }
-
- this.CurrentSubpage = new DisconnectedRemotePageViewModel(reason)
- {
- OkClicked = new RelayCommand(() =>
- {
- this.CurrentSubpage = _notConnectedPage;
- })
- };
-
- if (_mainPage is IDisposable d)
- {
- d.Dispose();
- }
- _mainPage = null;
- });
-
- }
-
- private void OnConnected(object? sender, ConnectionStateTracker.ConnectionStateChangedEventArgs eventArgs)
- {
- Dispatcher.UIThread.Post(() =>
- {
- _mainPage ??= new MainRemotePageViewModel(Remote, DeviceList);
- this.CurrentSubpage = _mainPage;
- });
- }
-
- public void Dispose()
- {
- if (this.Remote?.Socket?.ConnectionState is { } state)
- {
- state.Disconnected -= OnDisconnected;
- state.Connected -= OnConnected;
- }
-
- DeviceList.Dispose();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/DeviceInfoView.axaml.cs b/Client/UniScan.Client.App/Views/Controls/DeviceInfoView.axaml.cs
deleted file mode 100644
index 4bf7467..0000000
--- a/Client/UniScan.Client.App/Views/Controls/DeviceInfoView.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.Views.Controls;
-
-public partial class DeviceInfoView : UserControl
-{
- public DeviceInfoView()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/DeviceListView.axaml b/Client/UniScan.Client.App/Views/Controls/DeviceListView.axaml
deleted file mode 100644
index d860bd6..0000000
--- a/Client/UniScan.Client.App/Views/Controls/DeviceListView.axaml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Client/UniScan.Client.App/Views/Controls/DeviceListView.axaml.cs b/Client/UniScan.Client.App/Views/Controls/DeviceListView.axaml.cs
deleted file mode 100644
index 8b6e8c3..0000000
--- a/Client/UniScan.Client.App/Views/Controls/DeviceListView.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.Views.Controls;
-
-public partial class DeviceListView : UserControl
-{
- public DeviceListView()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/DeviceSidebarView.axaml.cs b/Client/UniScan.Client.App/Views/Controls/DeviceSidebarView.axaml.cs
deleted file mode 100644
index 2b903db..0000000
--- a/Client/UniScan.Client.App/Views/Controls/DeviceSidebarView.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.Views.Controls;
-
-public partial class DeviceSidebarView : UserControl
-{
- public DeviceSidebarView()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/RemoteControlView.axaml.cs b/Client/UniScan.Client.App/Views/Controls/RemoteControlView.axaml.cs
deleted file mode 100644
index 47038d2..0000000
--- a/Client/UniScan.Client.App/Views/Controls/RemoteControlView.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.Views.Controls;
-
-public partial class RemoteControlView : UserControl
-{
- public RemoteControlView()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Dialogs/AddRemoteDialogView.axaml.cs b/Client/UniScan.Client.App/Views/Dialogs/AddRemoteDialogView.axaml.cs
deleted file mode 100644
index dbb26b5..0000000
--- a/Client/UniScan.Client.App/Views/Dialogs/AddRemoteDialogView.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.Views.Dialogs;
-
-public partial class AddRemoteDialogView : UserControl
-{
- public AddRemoteDialogView()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Pages/EmptyPageView.axaml b/Client/UniScan.Client.App/Views/Global/EmptyPageView.axaml
similarity index 83%
rename from Client/UniScan.Client.App/Views/Pages/EmptyPageView.axaml
rename to Client/UniScan.Client.App/Views/Global/EmptyPageView.axaml
index c046718..492c237 100644
--- a/Client/UniScan.Client.App/Views/Pages/EmptyPageView.axaml
+++ b/Client/UniScan.Client.App/Views/Global/EmptyPageView.axaml
@@ -3,5 +3,5 @@
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"
- x:Class="UniScan.Client.App.Views.Pages.EmptyPageView">
+ x:Class="UniScan.Client.App.Views.Global.EmptyPageView">
diff --git a/Client/UniScan.Client.App/Views/Pages/EmptyPageView.axaml.cs b/Client/UniScan.Client.App/Views/Global/EmptyPageView.axaml.cs
similarity index 77%
rename from Client/UniScan.Client.App/Views/Pages/EmptyPageView.axaml.cs
rename to Client/UniScan.Client.App/Views/Global/EmptyPageView.axaml.cs
index 586f0a2..2ede4b4 100644
--- a/Client/UniScan.Client.App/Views/Pages/EmptyPageView.axaml.cs
+++ b/Client/UniScan.Client.App/Views/Global/EmptyPageView.axaml.cs
@@ -1,6 +1,6 @@
using Avalonia.Controls;
-namespace UniScan.Client.App.Views.Pages;
+namespace UniScan.Client.App.Views.Global;
public partial class EmptyPageView : UserControl
{
diff --git a/Client/UniScan.Client.App/Views/Global/EmptyPageViewModel.cs b/Client/UniScan.Client.App/Views/Global/EmptyPageViewModel.cs
new file mode 100644
index 0000000..74914d6
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Global/EmptyPageViewModel.cs
@@ -0,0 +1,8 @@
+using UniScan.Client.App.Views.ViewModel;
+
+namespace UniScan.Client.App.Views.Global;
+
+public class EmptyPageViewModel : ViewModelBase
+{
+
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/HeadedSeparatorControl.axaml b/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControl.axaml
similarity index 61%
rename from Client/UniScan.Client.App/Views/Controls/HeadedSeparatorControl.axaml
rename to Client/UniScan.Client.App/Views/Global/HeadedSeparatorControl.axaml
index fd0326e..6013cc9 100644
--- a/Client/UniScan.Client.App/Views/Controls/HeadedSeparatorControl.axaml
+++ b/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControl.axaml
@@ -2,13 +2,11 @@
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:local="clr-namespace:UniScan.Client.App.Views.Controls"
- xmlns:controls="clr-namespace:UniScan.Client.App.Views.Controls"
- xmlns:local1="clr-namespace:UniScan.Client.App.Views.Controls"
+ xmlns:global="clr-namespace:UniScan.Client.App.Views.Global"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.Controls.HeadedSeparatorControl">
+ x:Class="UniScan.Client.App.Views.Global.HeadedSeparatorControl">
-
+
diff --git a/Client/UniScan.Client.App/Views/Controls/HeadedSeparatorControl.axaml.cs b/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControl.axaml.cs
similarity index 91%
rename from Client/UniScan.Client.App/Views/Controls/HeadedSeparatorControl.axaml.cs
rename to Client/UniScan.Client.App/Views/Global/HeadedSeparatorControl.axaml.cs
index ee64e7b..4a25f25 100644
--- a/Client/UniScan.Client.App/Views/Controls/HeadedSeparatorControl.axaml.cs
+++ b/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControl.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia;
using Avalonia.Controls;
-namespace UniScan.Client.App.Views.Controls;
+namespace UniScan.Client.App.Views.Global;
public partial class HeadedSeparatorControl : UserControl
{
diff --git a/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControlViewModel.cs b/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControlViewModel.cs
new file mode 100644
index 0000000..0ad2355
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Global/HeadedSeparatorControlViewModel.cs
@@ -0,0 +1,8 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Global;
+
+public class HeadedSeparatorControlViewModel : UserControl
+{
+
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/LoadingView.axaml b/Client/UniScan.Client.App/Views/Global/LoadingView.axaml
similarity index 53%
rename from Client/UniScan.Client.App/Views/LoadingView.axaml
rename to Client/UniScan.Client.App/Views/Global/LoadingView.axaml
index 1d1af18..a0c6ec0 100644
--- a/Client/UniScan.Client.App/Views/LoadingView.axaml
+++ b/Client/UniScan.Client.App/Views/Global/LoadingView.axaml
@@ -2,24 +2,21 @@
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:viewModels="clr-namespace:UniScan.Client.App.ViewModels"
- xmlns:viewModels1="clr-namespace:UniScan.Client.App.ViewModels"
- xmlns:viewModels2="clr-namespace:UniScan.Client.App.ViewModels"
- xmlns:app="clr-namespace:UniScan.Client.App"
+ xmlns:global="clr-namespace:UniScan.Client.App.Views.Global"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.LoadingView"
- x:DataType="viewModels2:LoadingViewModel">
+ x:Class="UniScan.Client.App.Views.Global.LoadingView"
+ x:DataType="global:LoadingViewModel">
-
- Loading...
+
+
-
+
diff --git a/Client/UniScan.Client.App/Views/LoadingView.axaml.cs b/Client/UniScan.Client.App/Views/Global/LoadingView.axaml.cs
similarity index 77%
rename from Client/UniScan.Client.App/Views/LoadingView.axaml.cs
rename to Client/UniScan.Client.App/Views/Global/LoadingView.axaml.cs
index 03755dd..f140d20 100644
--- a/Client/UniScan.Client.App/Views/LoadingView.axaml.cs
+++ b/Client/UniScan.Client.App/Views/Global/LoadingView.axaml.cs
@@ -1,6 +1,6 @@
using Avalonia.Controls;
-namespace UniScan.Client.App.Views;
+namespace UniScan.Client.App.Views.Global;
public partial class LoadingView : UserControl
{
diff --git a/Client/UniScan.Client.App/ViewModels/LoadingViewModel.cs b/Client/UniScan.Client.App/Views/Global/LoadingViewModel.cs
similarity index 52%
rename from Client/UniScan.Client.App/ViewModels/LoadingViewModel.cs
rename to Client/UniScan.Client.App/Views/Global/LoadingViewModel.cs
index af4cc85..a17e3b8 100644
--- a/Client/UniScan.Client.App/ViewModels/LoadingViewModel.cs
+++ b/Client/UniScan.Client.App/Views/Global/LoadingViewModel.cs
@@ -1,15 +1,18 @@
-using UniScan.Client.App.Core.Pipeline;
+using Shiki.TaskPipeline;
+using UniScan.Client.App.Views.ViewModel;
-namespace UniScan.Client.App.ViewModels;
+namespace UniScan.Client.App.Views.Global;
public class LoadingViewModel : ViewModelBase
{
public static string VersionString => $"UniScan Client v{UniScanApp.SoftwareInfo.Version} (Platform v{UniScanApp.PlatformVersion})";
public TaskPipeline TaskPipeline { get; }
+ public string LoadingText { get; }
- public LoadingViewModel(TaskPipeline taskPipeline)
+ public LoadingViewModel(string loadingText, TaskPipeline taskPipeline)
{
+ LoadingText = loadingText;
TaskPipeline = taskPipeline;
}
}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Home/HomePageView.axaml b/Client/UniScan.Client.App/Views/Home/HomePageView.axaml
new file mode 100644
index 0000000..8273b1d
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Home/HomePageView.axaml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/UniScan.Client.App/Views/Home/HomePageView.axaml.cs b/Client/UniScan.Client.App/Views/Home/HomePageView.axaml.cs
new file mode 100644
index 0000000..c24b492
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Home/HomePageView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Home;
+
+public partial class HomePageView : ContentPage
+{
+ public HomePageView()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Pages/MainPageViewModel.cs b/Client/UniScan.Client.App/Views/Home/HomePageViewModel.cs
similarity index 77%
rename from Client/UniScan.Client.App/ViewModels/Pages/MainPageViewModel.cs
rename to Client/UniScan.Client.App/Views/Home/HomePageViewModel.cs
index b288070..0397a14 100644
--- a/Client/UniScan.Client.App/ViewModels/Pages/MainPageViewModel.cs
+++ b/Client/UniScan.Client.App/Views/Home/HomePageViewModel.cs
@@ -2,33 +2,34 @@
using System.Collections.Generic;
using ObservableCollections;
using R3;
-using UniScan.Client.Core.Config.Remote;
-using UniScan.Client.Core.Config.Types;
+using UniScan.Client.App.Views.Remote;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
-namespace UniScan.Client.App.ViewModels.Pages;
+namespace UniScan.Client.App.Views.Home;
-public class RemoteConnectionStateFilter : ISynchronizedViewFilter
+public class RemoteConnectionStateFilter : ISynchronizedViewFilter
{
- public bool IsMatch(RemoteServer value, RemoteViewModel view)
+ public bool IsMatch(RemoteServer value, RemoteRootPageViewModel rootPageView)
{
return value.Connected.CurrentValue;
}
}
-public partial class MainPageViewModel : ViewModelBase, IDisposable
+public partial class HomePageViewModel : ViewModelBase, IDisposable
{
- public INotifyCollectionChangedSynchronizedViewList ConnectedRemotesView { get; }
- private readonly ISynchronizedView _remotesView;
+ public INotifyCollectionChangedSynchronizedViewList ConnectedRemotesView { get; }
+ private readonly ISynchronizedView _remotesView;
private readonly Dictionary _subscriptions = [];
private readonly IRemoteManager _remoteManager;
- public MainPageViewModel(IRemoteManager remoteManager)
+ public HomePageViewModel(IServiceProvider provider, IRemoteManager remoteManager)
{
_remoteManager = remoteManager;
- _remotesView = remoteManager.Remotes.CreateView(remote => new RemoteViewModel(remote));
+ _remotesView = remoteManager.Remotes.CreateView(remote => new RemoteRootPageViewModel(provider, remote));
_remotesView.AttachFilter(new RemoteConnectionStateFilter());
ConnectedRemotesView = _remotesView.ToNotifyCollectionChanged(SynchronizationContextCollectionEventDispatcher.Current);
diff --git a/Client/UniScan.Client.App/Views/MainView.axaml b/Client/UniScan.Client.App/Views/MainView.axaml
index c4ef707..f134d3e 100644
--- a/Client/UniScan.Client.App/Views/MainView.axaml
+++ b/Client/UniScan.Client.App/Views/MainView.axaml
@@ -1,30 +1,22 @@
+ xmlns:views="clr-namespace:UniScan.Client.App.Views"
+ xmlns:global="clr-namespace:UniScan.Client.App.Views.Global"
+ xmlns:remote="clr-namespace:UniScan.Client.App.Views.Remote"
+ x:DataType="views:MainViewModel">
-
+
+ DrawerLayoutBehavior="CompactOverlay" x:Name="MainDrawerPage"
+ CompactDrawerLength="60">
@@ -32,27 +24,27 @@
-
+
-
+
-
-
+
+
- -->
-
-
-
-
-
-
-
-
-
-
diff --git a/Client/UniScan.Client.App/Views/Pages/MainRemotePageView.axaml.cs b/Client/UniScan.Client.App/Views/Pages/MainRemotePageView.axaml.cs
deleted file mode 100644
index 9081ab0..0000000
--- a/Client/UniScan.Client.App/Views/Pages/MainRemotePageView.axaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Avalonia.Controls;
-
-namespace UniScan.Client.App.Views.Pages;
-
-public partial class MainRemotePageView : UserControl
-{
- public MainRemotePageView()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Pages/NotConnectedRemotePageView.axaml b/Client/UniScan.Client.App/Views/Pages/NotConnectedRemotePageView.axaml
deleted file mode 100644
index 4d76553..0000000
--- a/Client/UniScan.Client.App/Views/Pages/NotConnectedRemotePageView.axaml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/Client/UniScan.Client.App/Views/Dialogs/AddRemoteDialogView.axaml b/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialog.axaml
similarity index 74%
rename from Client/UniScan.Client.App/Views/Dialogs/AddRemoteDialogView.axaml
rename to Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialog.axaml
index 4c95f01..4f02c96 100644
--- a/Client/UniScan.Client.App/Views/Dialogs/AddRemoteDialogView.axaml
+++ b/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialog.axaml
@@ -2,22 +2,17 @@
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:system="clr-namespace:System;assembly=System.Runtime"
- xmlns:dialogs1="clr-namespace:UniScan.Client.App.ViewModels.Dialogs"
xmlns:views="clr-namespace:UniScan.Client.App.Views"
- xmlns:util="clr-namespace:UniScan.Client.App.UI.Util"
+ xmlns:conversion="clr-namespace:UniScan.Client.App.UI.Conversion"
+ xmlns:action="clr-namespace:UniScan.Client.App.Views.Remote.Action"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.Dialogs.AddRemoteDialogView"
- x:DataType="dialogs1:AddRemoteDialogViewModel"
- Width="{Binding $parent[views:MainView].Bounds.Width, Converter={util:RelativeUnitConverter Min=200, Percentage=0.50}}"
- Height="{Binding $parent[views:MainView].Bounds.Height, Converter={util:RelativeUnitConverter Min=200, Percentage=0.50}}"
+ x:Class="UniScan.Client.App.Views.Remote.Action.AddRemoteDialog"
+ x:DataType="action:AddRemoteDialogViewModel"
+ Width="{Binding $parent[views:MainView].Bounds.Width, Converter={conversion:RelativeUnitConverter Min=200, Percentage=0.50}}"
+ Height="{Binding $parent[views:MainView].Bounds.Height, Converter={conversion:RelativeUnitConverter Min=200, Percentage=0.50}}"
Padding="6">
-
-
-
diff --git a/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialog.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialog.axaml.cs
new file mode 100644
index 0000000..79d6f3e
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialog.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote.Action;
+
+public partial class AddRemoteDialog : UserControl
+{
+ public AddRemoteDialog()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/ViewModels/Dialogs/AddRemoteDialogViewModel.cs b/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialogViewModel.cs
similarity index 91%
rename from Client/UniScan.Client.App/ViewModels/Dialogs/AddRemoteDialogViewModel.cs
rename to Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialogViewModel.cs
index 7906f0d..1f38f0e 100644
--- a/Client/UniScan.Client.App/ViewModels/Dialogs/AddRemoteDialogViewModel.cs
+++ b/Client/UniScan.Client.App/Views/Remote/Action/AddRemoteDialogViewModel.cs
@@ -5,19 +5,17 @@
using DialogHostAvalonia;
using ObservableCollections;
using UniScan.Client.App.UI.ConnectionMethod;
-using UniScan.Client.Core.Config.Types;
+using UniScan.Client.App.Views.ViewModel;
using UniScan.Client.Core.DI.Factory;
+using UniScan.Client.Core.Remote;
using UniScan.Network.Client.Remote.Connection;
-namespace UniScan.Client.App.ViewModels.Dialogs;
+namespace UniScan.Client.App.Views.Remote.Action;
public partial class AddRemoteDialogViewModel : ViewModelBase
{
private readonly IRemoteFactory _remoteFactory;
- [ObservableProperty]
- public partial string? DisplayName { get; set; }
-
[ObservableProperty]
public partial ConnectionMethodFactoryViewModelSource.ConnectionMethodViewModelFactoryPair? SelectedMethodFactory { get; set; }
@@ -47,7 +45,7 @@ public void Confirm()
return;
}
- CreatedRemote = _remoteFactory.Create(DisplayName ?? "New Remote", method);
+ CreatedRemote = _remoteFactory.Create(Guid.NewGuid(), method);
DialogHost.Close("MainDialogHost", CreatedRemote);
}
diff --git a/Client/UniScan.Client.App/Views/ConnectionMethod/TCPConnectionMethodFactoryView.axaml b/Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryView.axaml
similarity index 63%
rename from Client/UniScan.Client.App/Views/ConnectionMethod/TCPConnectionMethodFactoryView.axaml
rename to Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryView.axaml
index 92d75a4..eb82f5e 100644
--- a/Client/UniScan.Client.App/Views/ConnectionMethod/TCPConnectionMethodFactoryView.axaml
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryView.axaml
@@ -2,10 +2,10 @@
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:connectionMethod="clr-namespace:UniScan.Client.App.ViewModels.ConnectionMethod"
+ xmlns:connectionMethod1="clr-namespace:UniScan.Client.App.Views.Remote.Connection.ConnectionMethod"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.ConnectionMethod.TCPConnectionMethodFactoryView"
- x:DataType="connectionMethod:TCPConnectionMethodFactoryViewModel">
+ x:Class="UniScan.Client.App.Views.Remote.Connection.ConnectionMethod.TCPConnectionMethodFactoryView"
+ x:DataType="connectionMethod1:TCPConnectionMethodFactoryViewModel">
diff --git a/Client/UniScan.Client.App/Views/ConnectionMethod/TCPConnectionMethodFactoryView.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryView.axaml.cs
similarity index 65%
rename from Client/UniScan.Client.App/Views/ConnectionMethod/TCPConnectionMethodFactoryView.axaml.cs
rename to Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryView.axaml.cs
index d2488a3..43125f7 100644
--- a/Client/UniScan.Client.App/Views/ConnectionMethod/TCPConnectionMethodFactoryView.axaml.cs
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryView.axaml.cs
@@ -1,8 +1,6 @@
-using Avalonia;
using Avalonia.Controls;
-using Avalonia.Markup.Xaml;
-namespace UniScan.Client.App.Views.ConnectionMethod;
+namespace UniScan.Client.App.Views.Remote.Connection.ConnectionMethod;
public partial class TCPConnectionMethodFactoryView : UserControl
{
diff --git a/Client/UniScan.Client.App/ViewModels/ConnectionMethod/TCPConnectionMethodFactoryViewModel.cs b/Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryViewModel.cs
similarity index 92%
rename from Client/UniScan.Client.App/ViewModels/ConnectionMethod/TCPConnectionMethodFactoryViewModel.cs
rename to Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryViewModel.cs
index 93abb6f..959adfe 100644
--- a/Client/UniScan.Client.App/ViewModels/ConnectionMethod/TCPConnectionMethodFactoryViewModel.cs
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/ConnectionMethod/TCPConnectionMethodFactoryViewModel.cs
@@ -1,12 +1,12 @@
-using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using CommunityToolkit.Mvvm.ComponentModel;
using UniScan.Client.App.UI.ConnectionMethod;
+using UniScan.Client.App.Views.ViewModel;
using UniScan.Network.Client.Remote.Connection.Methods;
-namespace UniScan.Client.App.ViewModels.ConnectionMethod;
+namespace UniScan.Client.App.Views.Remote.Connection.ConnectionMethod;
#if !browser
[ConnectionMethodFactoryViewModel("TCP")]
diff --git a/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageView.axaml b/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageView.axaml
new file mode 100644
index 0000000..e2be7bd
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageView.axaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/UniScan.Client.App/Views/Pages/DisconnectedRemotePageView.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageView.axaml.cs
similarity index 76%
rename from Client/UniScan.Client.App/Views/Pages/DisconnectedRemotePageView.axaml.cs
rename to Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageView.axaml.cs
index f80c2b5..2c4d088 100644
--- a/Client/UniScan.Client.App/Views/Pages/DisconnectedRemotePageView.axaml.cs
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageView.axaml.cs
@@ -1,6 +1,6 @@
using Avalonia.Controls;
-namespace UniScan.Client.App.Views.Pages;
+namespace UniScan.Client.App.Views.Remote.Connection;
public partial class DisconnectedRemotePageView : UserControl
{
diff --git a/Client/UniScan.Client.App/ViewModels/Pages/DisconnectedRemotePageViewModel.cs b/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageViewModel.cs
similarity index 50%
rename from Client/UniScan.Client.App/ViewModels/Pages/DisconnectedRemotePageViewModel.cs
rename to Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageViewModel.cs
index 2d07b75..5ef952c 100644
--- a/Client/UniScan.Client.App/ViewModels/Pages/DisconnectedRemotePageViewModel.cs
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/DisconnectedRemotePageViewModel.cs
@@ -1,9 +1,13 @@
using CommunityToolkit.Mvvm.Input;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
-namespace UniScan.Client.App.ViewModels.Pages;
+namespace UniScan.Client.App.Views.Remote.Connection;
-public partial class DisconnectedRemotePageViewModel(string reason) : ViewModelBase
+public partial class DisconnectedRemotePageViewModel(string reason, RemoteServer? remote) : ViewModelBase
{
public string Reason { get; } = reason;
+ public RemoteServer? Remote { get; } = remote;
+
public IRelayCommand OkClicked { get; init; } = new RelayCommand(() => {});
}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageView.axaml b/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageView.axaml
new file mode 100644
index 0000000..8ca8627
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageView.axaml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/UniScan.Client.App/Views/Pages/NotConnectedRemotePageView.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageView.axaml.cs
similarity index 76%
rename from Client/UniScan.Client.App/Views/Pages/NotConnectedRemotePageView.axaml.cs
rename to Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageView.axaml.cs
index af2ad99..288b198 100644
--- a/Client/UniScan.Client.App/Views/Pages/NotConnectedRemotePageView.axaml.cs
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageView.axaml.cs
@@ -1,6 +1,6 @@
using Avalonia.Controls;
-namespace UniScan.Client.App.Views.Pages;
+namespace UniScan.Client.App.Views.Remote.Connection;
public partial class NotConnectedRemotePageView : UserControl
{
diff --git a/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageViewModel.cs b/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageViewModel.cs
new file mode 100644
index 0000000..d1f668c
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Connection/NotConnectedRemotePageViewModel.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.Input;
+using R3;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
+using UniScan.Client.Core.Remote.Pipeline;
+
+namespace UniScan.Client.App.Views.Remote.Connection;
+
+public partial class NotConnectedRemotePageViewModel(IServiceProvider provider, RemoteServer remote) : ViewModelBase
+{
+ public RemoteServer Remote { get; set; } = remote;
+
+ public bool HasConnectionMethod { get; set; } = remote.ConnectionMethod != null;
+
+ public event Action? OnConnecting;
+ public event Action? OnConnectFailed;
+
+ private CancellationTokenSource? _cts;
+ private IDisposable? _disposable;
+
+ [RelayCommand]
+ public async Task OnConnectClicked()
+ {
+ RemoteConnectionPipeline pipeline = new();
+
+ _cts = new CancellationTokenSource();
+ _disposable = Remote.Connected.Skip(1).Subscribe(OnConnectionStatusChanged);
+ OnConnecting?.Invoke(pipeline);
+
+ try
+ {
+ await pipeline.Pipeline.RunAsync(new RemoteConnectionPipeline.TaskContexts.ConnectionContext(provider,
+ remote), _cts.Token);
+ }
+ catch (Exception e)
+ {
+ OnConnectFailed?.Invoke(e);
+ }
+ }
+
+ private void OnConnectionStatusChanged(bool connected)
+ {
+ if (!connected)
+ {
+ _cts?.Cancel();
+ _cts = null;
+
+ _disposable?.Dispose();
+ _disposable = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/DeviceInfoView.axaml b/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControl.axaml
similarity index 62%
rename from Client/UniScan.Client.App/Views/Controls/DeviceInfoView.axaml
rename to Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControl.axaml
index 6a58a5f..c990fab 100644
--- a/Client/UniScan.Client.App/Views/Controls/DeviceInfoView.axaml
+++ b/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControl.axaml
@@ -2,31 +2,30 @@
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:controls="clr-namespace:UniScan.Client.App.ViewModels.Controls"
- xmlns:controls1="clr-namespace:UniScan.Client.App.ViewModels.Controls"
+ xmlns:device="clr-namespace:UniScan.Client.App.Views.Remote.Device"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.Controls.DeviceInfoView"
- x:DataType="controls1:DeviceInfoViewModel">
-
+ x:Class="UniScan.Client.App.Views.Remote.Device.DeviceInfoControl"
+ x:DataType="device:DeviceInfoControlViewModel">
+
-
+
+
+
+
-
+
-
-
-
-
diff --git a/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControl.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControl.axaml.cs
new file mode 100644
index 0000000..f3e377f
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControl.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote.Device;
+
+public partial class DeviceInfoControl : UserControl
+{
+ public DeviceInfoControl()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControlViewModel.cs b/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControlViewModel.cs
new file mode 100644
index 0000000..1b9a3b6
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Device/DeviceInfoControlViewModel.cs
@@ -0,0 +1,22 @@
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.Input;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
+using UniScan.Network.Data;
+using UniScan.Network.Packet.Packets.Serverbound.Subscription;
+
+namespace UniScan.Client.App.Views.Remote.Device;
+
+public partial class DeviceInfoControlViewModel(DeviceDto info, RemoteServer parentRemote) : ViewModelBase
+{
+ public DeviceDto Info { get; } = info;
+ public RemoteServer ParentRemote { get; } = parentRemote;
+
+ public bool HasModelInfo => Info.Specs != null;
+
+ [RelayCommand]
+ public async Task OnSubscribe()
+ {
+ await ParentRemote.Socket.SendRequestAsync(SubscribePacket.CreateRequest(Info.ScannerIdentifier));
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControl.axaml b/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControl.axaml
new file mode 100644
index 0000000..d00873e
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControl.axaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControl.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControl.axaml.cs
new file mode 100644
index 0000000..96446d5
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControl.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote.Device;
+
+public partial class DeviceListControl : UserControl
+{
+ public DeviceListControl()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControlViewModel.cs b/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControlViewModel.cs
new file mode 100644
index 0000000..51e7f25
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Device/DeviceListControlViewModel.cs
@@ -0,0 +1,16 @@
+using System;
+using ObservableCollections;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
+
+namespace UniScan.Client.App.Views.Remote.Device;
+
+public class DeviceListControlViewModel(RemoteServer server) : ViewModelBase, IDisposable
+{
+ public INotifyCollectionChangedSynchronizedViewList DevicesView { get; } = server.Devices.CreateView(kvp => new DeviceInfoControlViewModel(kvp.Value, server)).ToNotifyCollectionChanged(SynchronizationContextCollectionEventDispatcher.Current);
+
+ public void Dispose()
+ {
+ DevicesView.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/DeviceSidebarView.axaml b/Client/UniScan.Client.App/Views/Remote/Device/SidebarDeviceItemControl.axaml
similarity index 81%
rename from Client/UniScan.Client.App/Views/Controls/DeviceSidebarView.axaml
rename to Client/UniScan.Client.App/Views/Remote/Device/SidebarDeviceItemControl.axaml
index ea1652e..29ed018 100644
--- a/Client/UniScan.Client.App/Views/Controls/DeviceSidebarView.axaml
+++ b/Client/UniScan.Client.App/Views/Remote/Device/SidebarDeviceItemControl.axaml
@@ -3,6 +3,6 @@
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"
- x:Class="UniScan.Client.App.Views.Controls.DeviceSidebarView">
+ x:Class="UniScan.Client.App.Views.Remote.Device.SidebarDeviceItemControl">
Welcome to Avalonia!
diff --git a/Client/UniScan.Client.App/Views/Remote/Device/SidebarDeviceItemControl.axaml.cs b/Client/UniScan.Client.App/Views/Remote/Device/SidebarDeviceItemControl.axaml.cs
new file mode 100644
index 0000000..b6820a8
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/Device/SidebarDeviceItemControl.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote.Device;
+
+public partial class SidebarDeviceItemControl : UserControl
+{
+ public SidebarDeviceItemControl()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteInfoControl.axaml b/Client/UniScan.Client.App/Views/Remote/RemoteInfoControl.axaml
new file mode 100644
index 0000000..92fc214
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteInfoControl.axaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteInfoControl.axaml.cs b/Client/UniScan.Client.App/Views/Remote/RemoteInfoControl.axaml.cs
new file mode 100644
index 0000000..68b4edb
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteInfoControl.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public partial class RemoteInfoControl : UserControl
+{
+ public RemoteInfoControl()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteInfoControlViewModel.cs b/Client/UniScan.Client.App/Views/Remote/RemoteInfoControlViewModel.cs
new file mode 100644
index 0000000..331550f
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteInfoControlViewModel.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using System.Linq;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Network.Data.Info.Remote;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public class RemoteInfoControlViewModel(RemoteInfo info) : ViewModelBase
+{
+ public RemoteInfo Info { get; } = info;
+
+ public List Links { get; set; } =
+ [.. info.Branding.Links.Select(l => new RemoteLinkControlViewModel(l))];
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteLinkControl.axaml b/Client/UniScan.Client.App/Views/Remote/RemoteLinkControl.axaml
new file mode 100644
index 0000000..b0634fd
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteLinkControl.axaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteLinkControl.axaml.cs b/Client/UniScan.Client.App/Views/Remote/RemoteLinkControl.axaml.cs
new file mode 100644
index 0000000..b3aefb7
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteLinkControl.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public partial class RemoteLinkControl : UserControl
+{
+ public RemoteLinkControl()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteLinkControlViewModel.cs b/Client/UniScan.Client.App/Views/Remote/RemoteLinkControlViewModel.cs
new file mode 100644
index 0000000..0d6910e
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteLinkControlViewModel.cs
@@ -0,0 +1,9 @@
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Network.Data.Info.Remote;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public class RemoteLinkControlViewModel(RemoteLink link) : ViewModelBase
+{
+ public RemoteLink Link { get; } = link;
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemotePageView.axaml b/Client/UniScan.Client.App/Views/Remote/RemotePageView.axaml
new file mode 100644
index 0000000..fc0055a
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemotePageView.axaml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Client/UniScan.Client.App/Views/Remote/RemotePageView.axaml.cs b/Client/UniScan.Client.App/Views/Remote/RemotePageView.axaml.cs
new file mode 100644
index 0000000..726bdf1
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemotePageView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public partial class RemotePageView : UserControl
+{
+ public RemotePageView()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemotePageViewModel.cs b/Client/UniScan.Client.App/Views/Remote/RemotePageViewModel.cs
new file mode 100644
index 0000000..a988c32
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemotePageViewModel.cs
@@ -0,0 +1,37 @@
+using System;
+using CommunityToolkit.Mvvm.ComponentModel;
+using R3;
+using UniScan.Client.App.Views.Remote.Device;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public partial class RemotePageViewModel : ViewModelBase, IDisposable
+{
+ public RemoteServer Remote { get; set; }
+
+ [ObservableProperty]
+ public partial RemoteInfoControlViewModel? RemoteInfoViewModel { get; set; }
+
+ public DeviceListControlViewModel DeviceListControl { get; }
+
+ private readonly CompositeDisposable _disposables = new();
+
+ public RemotePageViewModel(RemoteServer remote, DeviceListControlViewModel deviceListControl, Observable remoteInfoViewModel)
+ {
+ Remote = remote;
+ DeviceListControl = deviceListControl;
+
+ remoteInfoViewModel.Subscribe(r =>
+ {
+ RemoteInfoViewModel = r;
+ }).AddTo(_disposables);
+ }
+
+ public void Dispose()
+ {
+ DeviceListControl.Dispose();
+ _disposables.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/RemoteView.axaml b/Client/UniScan.Client.App/Views/Remote/RemoteRootPageView.axaml
similarity index 61%
rename from Client/UniScan.Client.App/Views/RemoteView.axaml
rename to Client/UniScan.Client.App/Views/Remote/RemoteRootPageView.axaml
index 7da8933..575f971 100644
--- a/Client/UniScan.Client.App/Views/RemoteView.axaml
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteRootPageView.axaml
@@ -2,10 +2,9 @@
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:viewModels="clr-namespace:UniScan.Client.App.ViewModels"
- xmlns:viewModels1="clr-namespace:UniScan.Client.App.ViewModels"
+ xmlns:remote="clr-namespace:UniScan.Client.App.Views.Remote"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.RemoteView"
- x:DataType="viewModels1:RemoteViewModel">
+ x:Class="UniScan.Client.App.Views.Remote.RemoteRootPageView"
+ x:DataType="remote:RemoteRootPageViewModel">
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteRootPageView.axaml.cs b/Client/UniScan.Client.App/Views/Remote/RemoteRootPageView.axaml.cs
new file mode 100644
index 0000000..a6ce130
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteRootPageView.axaml.cs
@@ -0,0 +1,11 @@
+using Avalonia.Controls;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public partial class RemoteRootPageView : UserControl
+{
+ public RemoteRootPageView()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Remote/RemoteRootPageViewModel.cs b/Client/UniScan.Client.App/Views/Remote/RemoteRootPageViewModel.cs
new file mode 100644
index 0000000..4f20044
--- /dev/null
+++ b/Client/UniScan.Client.App/Views/Remote/RemoteRootPageViewModel.cs
@@ -0,0 +1,109 @@
+using System;
+using Avalonia.Threading;
+using CommunityToolkit.Mvvm.Input;
+using R3;
+using Shiki.Common.Identity.Slug;
+using Shiki.Common.Identity.Slug.Formatting.Formatters;
+using UniScan.Client.App.Views.Global;
+using UniScan.Client.App.Views.Remote.Connection;
+using UniScan.Client.App.Views.Remote.Device;
+using UniScan.Client.App.Views.ViewModel;
+using UniScan.Client.Core.Remote;
+using UniScan.Network.Util;
+
+namespace UniScan.Client.App.Views.Remote;
+
+public class RemoteRootPageViewModel : SubPagedViewModelBase, IDisposable
+{
+ public RemoteServer Remote { get; set; }
+
+ private readonly NotConnectedRemotePageViewModel _notConnectedPage;
+ private RemotePageViewModel? _mainPage;
+
+ public DeviceListControlViewModel DeviceListControl { get; }
+
+ public BehaviorSubject InfoViewModelStream { get; } = new(null);
+ public RemoteInfoControlViewModel? InfoViewModel => InfoViewModelStream.Value;
+
+ public RemoteRootPageViewModel(IServiceProvider provider, RemoteServer remote) : base(new NotConnectedRemotePageViewModel(provider, remote), UniScanApp.Identifier.Derived("view_model", "remote", new Slug(Guid.NewGuid().ToString())))
+ {
+ this._notConnectedPage = (NotConnectedRemotePageViewModel)CurrentSubpage;
+ this._notConnectedPage.OnConnecting += (pipeline) =>
+ {
+ this.CurrentSubpage = new LoadingViewModel("Connecting...", pipeline.Pipeline);
+ };
+
+ this._notConnectedPage.OnConnectFailed += (ex) =>
+ {
+ this.CurrentSubpage = new DisconnectedRemotePageViewModel("Failed to connect to server! " + ex.Message, Remote)
+ {
+ OkClicked = new RelayCommand(() =>
+ {
+ this.CurrentSubpage = _notConnectedPage;
+ })
+ };
+ };
+
+ this.Remote = remote;
+ Remote.RemoteInfo.Subscribe((v) =>
+ {
+ RemoteInfoControlViewModel? n = v != null ? new RemoteInfoControlViewModel(v) : null;
+
+ InfoViewModelStream.OnNext(n);
+ OnPropertyChanged(nameof(InfoViewModel));
+ });
+
+ DeviceListControl = new DeviceListControlViewModel(remote);
+
+ this.Remote.Socket.ConnectionState.Disconnected += OnDisconnected;
+ this.Remote.Socket.ConnectionState.Connected += OnConnected;
+ }
+
+ private void OnDisconnected(object? sender, ConnectionStateTracker.ConnectionStateChangedEventArgs eventArgs)
+ {
+ Dispatcher.UIThread.Post(() =>
+ {
+ string reason = "Unknown reason, maybe there is more info in the logs.";
+ if (eventArgs.Channel.HasAttribute(ServerAttributes.DisconnectReasonAttribute))
+ {
+ reason = eventArgs.Channel.GetAttribute(ServerAttributes.DisconnectReasonAttribute).Get();
+ }
+
+ this.CurrentSubpage = new DisconnectedRemotePageViewModel(reason, Remote)
+ {
+ OkClicked = new RelayCommand(() =>
+ {
+ this.CurrentSubpage = _notConnectedPage;
+ })
+ };
+
+ //todo can we PLEASE manage state better!!!!!!
+ if (_mainPage is IDisposable d)
+ {
+ d.Dispose();
+ }
+ _mainPage = null;
+ });
+
+ }
+
+ private void OnConnected(object? sender, ConnectionStateTracker.ConnectionStateChangedEventArgs eventArgs)
+ {
+ Dispatcher.UIThread.Post(() =>
+ {
+ _mainPage ??= new RemotePageViewModel(Remote, DeviceListControl, InfoViewModelStream.AsObservable());
+ this.CurrentSubpage = _mainPage;
+ });
+ }
+
+ public void Dispose()
+ {
+ if (this.Remote?.Socket?.ConnectionState is { } state)
+ {
+ state.Disconnected -= OnDisconnected;
+ state.Connected -= OnConnected;
+ }
+
+ DeviceListControl.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/Client/UniScan.Client.App/Views/Controls/RemoteControlView.axaml b/Client/UniScan.Client.App/Views/Remote/SidebarRemoteItemControl.axaml
similarity index 53%
rename from Client/UniScan.Client.App/Views/Controls/RemoteControlView.axaml
rename to Client/UniScan.Client.App/Views/Remote/SidebarRemoteItemControl.axaml
index 1e60a00..82d20b1 100644
--- a/Client/UniScan.Client.App/Views/Controls/RemoteControlView.axaml
+++ b/Client/UniScan.Client.App/Views/Remote/SidebarRemoteItemControl.axaml
@@ -2,16 +2,16 @@
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:controls="clr-namespace:UniScan.Client.App.ViewModels.Controls"
- xmlns:controls1="clr-namespace:UniScan.Client.App.Views.Controls"
- xmlns:controls2="clr-namespace:UniScan.Client.App.ViewModels.Controls"
+ xmlns:asyncImageLoader="clr-namespace:AsyncImageLoader;assembly=AsyncImageLoader.Avalonia"
+ xmlns:remote="clr-namespace:UniScan.Client.App.Views.Remote"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:Class="UniScan.Client.App.Views.Controls.RemoteControlView"
- x:DataType="controls2:RemoteControlViewModel">
+ x:Class="UniScan.Client.App.Views.Remote.SidebarRemoteItemControl"
+ x:DataType="remote:SidebarRemoteItemControlViewModel">