Merge branch 'feature/api_service' into 'main'

Feature/api service

See merge request fabinfra/fabaccess/borepin!55
This commit is contained in:
TheJoKlLa 2022-06-13 20:02:13 +00:00
commit ebcdc708bb
129 changed files with 4197 additions and 3105 deletions

View File

@ -3,3 +3,6 @@
# MA0003: Add argument name to improve readability # MA0003: Add argument name to improve readability
dotnet_diagnostic.MA0003.severity = none dotnet_diagnostic.MA0003.severity = none
csharp_style_prefer_switch_expression=false:suggestion csharp_style_prefer_switch_expression=false:suggestion
# MA0051: Method is too long
dotnet_diagnostic.MA0051.severity = silent

2
.gitmodules vendored
View File

@ -16,5 +16,5 @@
[submodule "external/capnproto-dotnetcore"] [submodule "external/capnproto-dotnetcore"]
path = external/capnproto-dotnetcore path = external/capnproto-dotnetcore
url = https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git url = https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
branch = main branch = master
ignore = all ignore = all

View File

@ -68,7 +68,7 @@
<Version>8.1.97</Version> <Version>8.1.97</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.2" /> <PackageReference Include="Xamarin.Essentials" Version="1.7.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MainActivity.cs" /> <Compile Include="MainActivity.cs" />
@ -76,6 +76,11 @@
<Compile Include="PlatformInitializer.cs" /> <Compile Include="PlatformInitializer.cs" />
<Compile Include="Resources\Resource.designer.cs" /> <Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\APIBinder.cs" />
<Compile Include="Services\APIBindedService.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\APIService_New.cs" />
<Compile Include="Services\APIServiceConnection.cs" />
<Compile Include="Services\PreferenceStorageService.cs" /> <Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorage.cs" /> <Compile Include="Services\SecretStorage.cs" />
<Compile Include="Services\VersioningService.cs" /> <Compile Include="Services\VersioningService.cs" />
@ -87,6 +92,10 @@
<None Include="Properties\AndroidManifest.xml" /> <None Include="Properties\AndroidManifest.xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj">
<Project>{3251FCE9-FEA3-4662-8BEB-636BE6732D48}</Project>
<Name>FabAccessAPI</Name>
</ProjectReference>
<ProjectReference Include="..\Borepin\Borepin.csproj"> <ProjectReference Include="..\Borepin\Borepin.csproj">
<Project>{F93856BD-0C8D-4469-A8DB-6E513002BFD7}</Project> <Project>{F93856BD-0C8D-4469-A8DB-6E513002BFD7}</Project>
<Name>Borepin</Name> <Name>Borepin</Name>

View File

@ -1,4 +1,5 @@
using Borepin.Droid.Services; using Borepin.Droid.Services;
using Borepin.Service;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using Prism; using Prism;
@ -13,6 +14,8 @@ namespace Borepin.Droid
containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>(); containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>();
containerRegistry.Register<ISecretStorageService, SecretStorage>(); containerRegistry.Register<ISecretStorageService, SecretStorage>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }
} }
} }

View File

@ -0,0 +1,50 @@
using Android.App;
using Android.Content;
using Android.OS;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
[Service(Name= "org.fab_infra.fabaccess.APIService")]
public class APIBindedService : Android.App.Service
{
#region Private Members
private IAPI _API;
#endregion
#region Members
public IBinder Binder { get; private set; }
#endregion
#region Methods
public IAPI GetAPI()
{
return _API;
}
public override void OnCreate()
{
base.OnCreate();
_API = new API();
}
public override IBinder OnBind(Intent intent)
{
Binder = new APIBinder(this);
return Binder;
}
public override bool OnUnbind(Intent intent)
{
return base.OnUnbind(intent);
}
public override void OnDestroy()
{
Binder = null;
_API = null;
base.OnDestroy();
}
#endregion
}
}

View File

@ -0,0 +1,18 @@
using Android.OS;
namespace Borepin.Droid.Services
{
public class APIBinder : Binder
{
#region Constructors
public APIBinder(APIBindedService service)
{
Service = service;
}
#endregion
#region Members
public APIBindedService Service { get; private set; }
#endregion
}
}

View File

@ -0,0 +1,23 @@
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
public class APIService : IAPIService
{
#region Private Members
private readonly IAPI _API;
#endregion
#region Constructors
public APIService()
{
_API = new API();
}
#endregion
public IAPI GetAPI()
{
return _API;
}
}
}

View File

@ -0,0 +1,32 @@
using Android.Content;
using Android.OS;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
class APIServiceConnection : Java.Lang.Object, IServiceConnection
{
#region Members
public bool IsConnected
{
get
{
return Binder != null;
}
}
public APIBinder Binder { get; private set; } = null;
#endregion
#region Methods
public void OnServiceConnected(ComponentName name, IBinder service)
{
Binder = service as APIBinder;
}
public void OnServiceDisconnected(ComponentName name)
{
Binder = null;
}
#endregion
}
}

View File

@ -0,0 +1,28 @@
using Android.App;
using Android.Content;
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
public class APIService_New : IAPIService
{
#region Private Members
private readonly APIServiceConnection _APIServiceConnection;
#endregion
#region Constructors
public APIService_New()
{
Context context = Application.Context;
Intent service = new Intent(context, typeof(APIBindedService));
context.BindService(service, _APIServiceConnection, Bind.AutoCreate);
}
#endregion
public IAPI GetAPI()
{
return _APIServiceConnection?.Binder?.Service?.GetAPI();
}
}
}

View File

@ -42,8 +42,8 @@
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\atk-sharp.dll</HintPath> <HintPath>..\..\..\..\..\..\..\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\atk-sharp.dll</HintPath>
</Reference> </Reference>
<Reference Include="DryIoc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL"> <Reference Include="DryIoc, Version=5.0.2.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL">
<HintPath>..\..\packages\DryIoc.dll.5.0.0\lib\net45\DryIoc.dll</HintPath> <HintPath>..\..\packages\DryIoc.dll.5.0.2\lib\net45\DryIoc.dll</HintPath>
</Reference> </Reference>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL"> <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>

View File

@ -12,7 +12,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" /> <assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" /> <bindingRedirect oldVersion="0.0.0.0-5.0.2.0" newVersion="5.0.2.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="DryIoc.dll" version="5.0.0" targetFramework="net48" /> <package id="DryIoc.dll" version="5.0.2" targetFramework="net48" />
<package id="OpenTK" version="3.2" targetFramework="net48" /> <package id="OpenTK" version="3.2" targetFramework="net48" />
<package id="Prism.Core" version="8.1.97" targetFramework="net48" /> <package id="Prism.Core" version="8.1.97" targetFramework="net48" />
<package id="Prism.DryIoc.Forms" version="8.1.97" targetFramework="net48" /> <package id="Prism.DryIoc.Forms" version="8.1.97" targetFramework="net48" />

View File

@ -98,6 +98,7 @@
</Compile> </Compile>
<Compile Include="PlatformInitializer.cs" /> <Compile Include="PlatformInitializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" /> <Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorageService.cs" /> <Compile Include="Services\SecretStorageService.cs" />
<Compile Include="Services\VersioningService.cs" /> <Compile Include="Services\VersioningService.cs" />
@ -181,9 +182,17 @@
</PackageReference> </PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" />
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.13" /> <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.13" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.2" /> <PackageReference Include="Xamarin.Essentials" Version="1.7.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\external\capnproto-dotnetcore\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj">
<Project>{c587aac3-50a7-4871-a50d-7880b6f24ef6}</Project>
<Name>Capnp.Net.Runtime</Name>
</ProjectReference>
<ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj">
<Project>{3251FCE9-FEA3-4662-8BEB-636BE6732D48}</Project>
<Name>FabAccessAPI</Name>
</ProjectReference>
<ProjectReference Include="..\Borepin\Borepin.csproj"> <ProjectReference Include="..\Borepin\Borepin.csproj">
<Project>{64ED6CAA-99A0-4EC4-B976-DCBD571F05D7}</Project> <Project>{64ED6CAA-99A0-4EC4-B976-DCBD571F05D7}</Project>
<Name>Borepin</Name> <Name>Borepin</Name>

View File

@ -3,6 +3,7 @@ using Prism;
using Prism.Ioc; using Prism.Ioc;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using Borepin.Service;
namespace Borepin.UWP namespace Borepin.UWP
{ {
@ -13,6 +14,8 @@ namespace Borepin.UWP
containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>(); containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>();
containerRegistry.Register<ISecretStorageService, SecretStorageService>(); containerRegistry.Register<ISecretStorageService, SecretStorageService>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }
} }
} }

View File

@ -0,0 +1,23 @@
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.UWP.Services
{
public class APIService : IAPIService
{
#region Private Members
private readonly IAPI _API;
#endregion
#region Constructors
public APIService()
{
_API = new API();
}
#endregion
public IAPI GetAPI()
{
return _API;
}
}
}

View File

@ -81,6 +81,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" /> <Compile Include="AppDelegate.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" /> <Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorageService.cs" /> <Compile Include="Services\SecretStorageService.cs" />
<Compile Include="Services\VersioningService.cs" /> <Compile Include="Services\VersioningService.cs" />
@ -185,13 +186,17 @@
<PackageReference Include="Prism.DryIoc.Forms"> <PackageReference Include="Prism.DryIoc.Forms">
<Version>8.1.97</Version> <Version>8.1.97</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Xamarin.Essentials" Version="1.7.2" /> <PackageReference Include="Xamarin.Essentials" Version="1.7.3" />
<PackageReference Include="Xamarin.Forms"> <PackageReference Include="Xamarin.Forms">
<Version>5.0.0.2401</Version> <Version>5.0.0.2401</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\FabAccessAPI\FabAccessAPI.csproj">
<Project>{3251FCE9-FEA3-4662-8BEB-636BE6732D48}</Project>
<Name>FabAccessAPI</Name>
</ProjectReference>
<ProjectReference Include="..\Borepin\Borepin.csproj"> <ProjectReference Include="..\Borepin\Borepin.csproj">
<Project>{F93856BD-0C8D-4469-A8DB-6E513002BFD7}</Project> <Project>{F93856BD-0C8D-4469-A8DB-6E513002BFD7}</Project>
<Name>Borepin</Name> <Name>Borepin</Name>

View File

@ -1,4 +1,5 @@
using Borepin.iOS.Services; using Borepin.iOS.Services;
using Borepin.Service;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using Prism; using Prism;
@ -13,6 +14,8 @@ namespace Borepin.iOS
containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>(); containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>();
containerRegistry.Register<ISecretStorageService, SecretStorageService>(); containerRegistry.Register<ISecretStorageService, SecretStorageService>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }
} }
} }

View File

@ -0,0 +1,23 @@
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.iOS.Services
{
public class APIService : IAPIService
{
#region Private Members
private readonly IAPI _API;
#endregion
#region Constructors
public APIService()
{
_API = new API();
}
#endregion
public IAPI GetAPI()
{
return _API;
}
}
}

View File

@ -59,8 +59,8 @@
</XamMacArch> </XamMacArch>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DryIoc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL"> <Reference Include="DryIoc, Version=5.0.2.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL">
<HintPath>..\..\packages\DryIoc.dll.5.0.0\lib\netstandard2.1\DryIoc.dll</HintPath> <HintPath>..\..\packages\DryIoc.dll.5.0.2\lib\netstandard2.1\DryIoc.dll</HintPath>
</Reference> </Reference>
<Reference Include="Prism, Version=8.1.97.5141, Culture=neutral, PublicKeyToken=40ee6c3a2184dc59, processorArchitecture=MSIL"> <Reference Include="Prism, Version=8.1.97.5141, Culture=neutral, PublicKeyToken=40ee6c3a2184dc59, processorArchitecture=MSIL">
<HintPath>..\..\packages\Prism.Core.8.1.97\lib\netstandard2.0\Prism.dll</HintPath> <HintPath>..\..\packages\Prism.Core.8.1.97\lib\netstandard2.0\Prism.dll</HintPath>

View File

@ -8,7 +8,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" /> <assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" /> <bindingRedirect oldVersion="0.0.0.0-5.0.2.0" newVersion="5.0.2.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="DryIoc.dll" version="5.0.0" targetFramework="xamarinmac20" /> <package id="DryIoc.dll" version="5.0.2" targetFramework="xamarinmac20" />
<package id="Prism.Core" version="8.1.97" targetFramework="xamarinmac20" /> <package id="Prism.Core" version="8.1.97" targetFramework="xamarinmac20" />
<package id="Prism.DryIoc.Forms" version="8.1.97" targetFramework="xamarinmac20" /> <package id="Prism.DryIoc.Forms" version="8.1.97" targetFramework="xamarinmac20" />
<package id="Prism.Forms" version="8.1.97" targetFramework="xamarinmac20" /> <package id="Prism.Forms" version="8.1.97" targetFramework="xamarinmac20" />

View File

@ -4,14 +4,14 @@ using Borepin.Page;
using Xamarin.Forms; using Xamarin.Forms;
using Borepin.Dialog; using Borepin.Dialog;
using Borepin.DialogModel; using Borepin.DialogModel;
using Borepin.Service.BFFH;
using Prism; using Prism;
using Borepin.Page.SetUpProcess; using Borepin.Page.SetUpProcess;
using Borepin.PageModel.SetUpProcess; using Borepin.PageModel.SetUpProcess;
using Borepin.Page.AddServerProcess; using Borepin.Page.AddServerProcess;
using Borepin.PageModel.AddServerProcess; using Borepin.PageModel.AddServerProcess;
using System; using System;
using Prism.Navigation; using Borepin.Service.Storage;
using NLog;
namespace Borepin namespace Borepin
{ {
@ -19,18 +19,16 @@ namespace Borepin
{ {
public App(IPlatformInitializer platformInitializer) : base(platformInitializer) public App(IPlatformInitializer platformInitializer) : base(platformInitializer)
{ {
var config = new NLog.Config.LoggingConfiguration();
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
config.AddRule(LogLevel.Trace, LogLevel.Fatal, logconsole);
LogManager.Configuration = config;
} }
protected override async void OnInitialized() protected override async void OnInitialized()
{ {
InitializeComponent(); InitializeComponent();
INavigationParameters parameters = new NavigationParameters()
{
{ "instance", 0 },
};
await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false); await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false);
} }
@ -47,8 +45,8 @@ namespace Borepin
containerRegistry.RegisterForNavigation<MachineListPage, MachineListPageModel>(); containerRegistry.RegisterForNavigation<MachineListPage, MachineListPageModel>();
containerRegistry.RegisterForNavigation<ServerListPage, ServerListPageModel>(); containerRegistry.RegisterForNavigation<ServerListPage, ServerListPageModel>();
containerRegistry.RegisterForNavigation<ServerPage, ServerPageModel>(); containerRegistry.RegisterForNavigation<ServerPage, ServerPageModel>();
containerRegistry.RegisterForNavigation<ScanPage, ScanPageModel>("ScanPage"); containerRegistry.RegisterForNavigation<ScanPage, ScanPageModel>();
containerRegistry.RegisterForNavigation<ScanPage, ScanURNPageModel>("ScanURNPage"); containerRegistry.RegisterForNavigation<ScanURNPage, ScanURNPageModel>();
#endregion #endregion
#region Register Sequence Navigation #region Register Sequence Navigation
@ -65,7 +63,13 @@ namespace Borepin
#endregion #endregion
#region Register Service #region Register Service
containerRegistry.RegisterSingleton<IBFFHService, BFFHService>(); containerRegistry.RegisterSingleton<ILoginStorageService, LoginStorageService>();
// NEED PLATFORM SPECIFIC SERVICE
// IPreferenceStorageService
// ISecretStorageService
// IVersioningService
// IAPIService
#endregion #endregion
} }
} }

View File

@ -1,9 +1,8 @@
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions; using FabAccessAPI;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xamarin.Forms;
namespace Borepin.Base namespace Borepin.Base
{ {
@ -13,15 +12,74 @@ namespace Borepin.Base
public abstract class ConnectionModelBase : PageModelBase public abstract class ConnectionModelBase : PageModelBase
{ {
#region Private Fields #region Private Fields
protected readonly IPageDialogService _PageDialogService; protected readonly IAPI _API;
protected readonly IBFFHService _BFFHService;
#endregion #endregion
#region Constructors #region Constructors
protected ConnectionModelBase(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bFFHService) : base(navigationService) protected ConnectionModelBase(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService)
{ {
_PageDialogService = pageDialogService; _API = apiService.GetAPI();
_BFFHService = bFFHService; _API.ConnectionStatusChanged += OnConnectionStatusChanged;
IsConnected = _API.IsConnected;
}
#endregion
#region Methods
public async void OnConnectionStatusChanged(object sender, ConnectionStatusChange args)
{
switch(args)
{
case ConnectionStatusChange.Connected:
IsConnected = true;
try
{
await LoadAPIData().ConfigureAwait(false);
}
catch
{
IsConnected = false;
await _API.Disconnect().ConfigureAwait(false);
_API.UnbindAllEvents();
}
break;
case ConnectionStatusChange.Reconnected:
try
{
await ReloadAPIData().ConfigureAwait(false);
}
catch
{
IsConnected = false;
await _API.Disconnect().ConfigureAwait(false);
_API.UnbindAllEvents();
}
break;
case ConnectionStatusChange.ConnectionLoss:
try
{
await _API.Reconnect().ConfigureAwait(false);
}
catch
{
IsConnected = false;
await _API.Disconnect().ConfigureAwait(false);
_API.UnbindAllEvents();
}
break;
case ConnectionStatusChange.Disconnected:
IsConnected = false;
break;
}
}
public virtual Task LoadAPIData()
{
return Task.CompletedTask;
}
public virtual Task ReloadAPIData()
{
return Task.CompletedTask;
} }
#endregion #endregion
@ -37,36 +95,23 @@ namespace Borepin.Base
} }
#endregion #endregion
#region Methods #region INavigationAware
/// <summary> public override async Task OnNavigatedToVirtual(INavigationParameters parameters)
/// Checks connection to Server.
/// Display message if Connection is lost.
/// </summary>
/// <returns>True if connection is ok.</returns>
public async Task<bool> CheckConnection()
{ {
try await base.OnNavigatedToVirtual(parameters).ConfigureAwait(false);
{
if(_BFFHService.CurrentConnection != null && !_BFFHService.IsConnected)
{
await _BFFHService.Reconnect().ConfigureAwait(false);
}
else if(_BFFHService.CurrentConnection == null)
{
return false;
}
return true; if(_API.IsConnected)
}
catch (ReconnectingFailedException)
{ {
Device.BeginInvokeOnMainThread(async () => try
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Lost connection to server.", "Ok").ConfigureAwait(false); await LoadAPIData().ConfigureAwait(false);
}); }
catch
IsConnected = false; {
return false; IsConnected = false;
await _API.Disconnect().ConfigureAwait(false);
_API.UnbindAllEvents();
}
} }
} }
#endregion #endregion

View File

@ -0,0 +1,22 @@
using System;
namespace Borepin.Base.Exceptions
{
public class InstanceIncorrectException : Exception
{
public InstanceIncorrectException()
{
}
public InstanceIncorrectException(string message) : base(message)
{
}
public InstanceIncorrectException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,5 +1,7 @@
using Prism.Mvvm; using NLog;
using Prism.Mvvm;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Borepin.Base namespace Borepin.Base
@ -9,12 +11,18 @@ namespace Borepin.Base
/// </summary> /// </summary>
public abstract class PageModelBase : BindableBase, INavigationAware public abstract class PageModelBase : BindableBase, INavigationAware
{ {
#region Logger
protected static readonly Logger Log = LogManager.GetCurrentClassLogger();
#endregion
#region Private Fields #region Private Fields
protected readonly INavigationService _NavigationService; protected readonly INavigationService _NavigationService;
protected readonly IPageDialogService _PageDialogService;
protected PageModelBase(INavigationService navigationService) protected PageModelBase(INavigationService navigationService, IPageDialogService pageDialogService)
{ {
_NavigationService = navigationService; _NavigationService = navigationService;
_PageDialogService = pageDialogService;
} }
#endregion #endregion
@ -30,17 +38,57 @@ namespace Borepin.Base
} }
#endregion #endregion
#region Data #region Mehtods
/// <summary> public virtual Task LoadInstance(object instance)
/// Load Data async {
/// </summary> return Task.CompletedTask;
/// <returns></returns> }
public abstract Task LoadData();
public virtual Task LoadFromParameters(INavigationParameters parameters)
{
return Task.CompletedTask;
}
public virtual Task<object> CreateInstance()
{
return Task.FromResult<object>(null);
}
#endregion #endregion
#region INavigationAware #region INavigationAware
public abstract void OnNavigatedTo(INavigationParameters parameters); public async void OnNavigatedTo(INavigationParameters parameters)
public abstract void OnNavigatedFrom(INavigationParameters parameters); {
await OnNavigatedToVirtual(parameters).ConfigureAwait(false);
IsBusy = false;
}
public async void OnNavigatedFrom(INavigationParameters parameters)
{
await OnNavigatedFromVirtual(parameters).ConfigureAwait(false);
}
public virtual async Task OnNavigatedToVirtual(INavigationParameters parameters)
{
if (parameters.ContainsKey("instance"))
{
await LoadInstance(parameters.GetValue<object>("instance")).ConfigureAwait(false);
}
else
{
Log.Trace("No instance");
await LoadInstance(null).ConfigureAwait(false);
}
await LoadFromParameters(parameters).ConfigureAwait(false);
}
public virtual async Task OnNavigatedFromVirtual(INavigationParameters parameters)
{
object instance = await CreateInstance().ConfigureAwait(false);
if (instance != null)
{
parameters.Add("instance", instance);
}
}
#endregion #endregion
} }
} }

View File

@ -21,17 +21,23 @@
</Target> </Target>
<ItemGroup> <ItemGroup>
<Compile Remove="Behaviour\**" /> <Compile Remove="Behaviour\**" />
<Compile Remove="Helpers\**" />
<Compile Remove="Properties\**" />
<EmbeddedResource Remove="Behaviour\**" /> <EmbeddedResource Remove="Behaviour\**" />
<EmbeddedResource Remove="Helpers\**" />
<EmbeddedResource Remove="Properties\**" />
<None Remove="Behaviour\**" /> <None Remove="Behaviour\**" />
<None Remove="Helpers\**" />
<None Remove="Properties\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="1.0.700"> <PackageReference Include="Meziantou.Analyzer" Version="1.0.702">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="NaturalSort.Extension" Version="3.2.0" /> <PackageReference Include="NaturalSort.Extension" Version="3.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Plugin.Multilingual" Version="1.0.2" /> <PackageReference Include="NLog" Version="5.0.0" />
<PackageReference Include="Prism.DryIoc.Forms" Version="8.1.97" /> <PackageReference Include="Prism.DryIoc.Forms" Version="8.1.97" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" /> <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
@ -47,6 +53,15 @@
<Compile Update="Page\AddServerProcess\SelectServerPage.xaml.cs"> <Compile Update="Page\AddServerProcess\SelectServerPage.xaml.cs">
<DependentUpon>SelectServerPage.xaml</DependentUpon> <DependentUpon>SelectServerPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Update="Page\ScanURNPage.xaml.cs">
<DependentUpon>ScanURNPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\UserPage.xaml.cs">
<DependentUpon>UserPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\UserListPage.xaml.cs">
<DependentUpon>UserListPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\MachineListPage.xaml.cs"> <Compile Update="Page\MachineListPage.xaml.cs">
<DependentUpon>MachineListPage.xaml</DependentUpon> <DependentUpon>MachineListPage.xaml</DependentUpon>
</Compile> </Compile>
@ -62,11 +77,6 @@
<Compile Update="Page\StartPage.xaml.cs"> <Compile Update="Page\StartPage.xaml.cs">
<DependentUpon>StartPage.xaml</DependentUpon> <DependentUpon>StartPage.xaml</DependentUpon>
</Compile> </Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Resources\Text\TextResource.Designer.cs"> <Compile Update="Resources\Text\TextResource.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@ -78,6 +88,9 @@
<Compile Update="View\MachineListItemView.xaml.cs"> <Compile Update="View\MachineListItemView.xaml.cs">
<DependentUpon>MachineListItemView.xaml</DependentUpon> <DependentUpon>MachineListItemView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Update="View\UserListItemView.xaml.cs">
<DependentUpon>UserListItemView.xaml</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Update="Dialog\ConfirmDialog.xaml"> <EmbeddedResource Update="Dialog\ConfirmDialog.xaml">
@ -119,10 +132,6 @@
<EmbeddedResource Update="Page\StartPage.xaml"> <EmbeddedResource Update="Page\StartPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Text\TextResource.resx"> <EmbeddedResource Update="Resources\Text\TextResource.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TextResource.Designer.cs</LastGenOutput> <LastGenOutput>TextResource.Designer.cs</LastGenOutput>

View File

@ -1,4 +1,5 @@
using System; using FabAccessAPI.Schema;
using System;
using System.Globalization; using System.Globalization;
using Xamarin.Forms; using Xamarin.Forms;
@ -8,9 +9,9 @@ namespace Borepin.Converter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
switch((FabAccessAPI.Schema.Machine.MachineState)value) switch((Machine.MachineState)value)
{ {
case (FabAccessAPI.Schema.Machine.MachineState.free): case Machine.MachineState.free:
return (Color)Application.Current.Resources["FirstColor"]; return (Color)Application.Current.Resources["FirstColor"];
default: default:
return (Color)Application.Current.Resources["SixthColor"]; return (Color)Application.Current.Resources["SixthColor"];

View File

@ -1,4 +1,5 @@
using System; using FabAccessAPI.Schema;
using System;
using System.Globalization; using System.Globalization;
using Xamarin.Forms; using Xamarin.Forms;
@ -8,20 +9,22 @@ namespace Borepin.Converter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
switch((FabAccessAPI.Schema.Machine.MachineState)value) switch((Machine.MachineState)value)
{ {
case (FabAccessAPI.Schema.Machine.MachineState.free): case Machine.MachineState.free:
return "Free"; return "Free";
case (FabAccessAPI.Schema.Machine.MachineState.inUse): case Machine.MachineState.inUse:
return "In Use"; return "In Use";
case (FabAccessAPI.Schema.Machine.MachineState.toCheck): case Machine.MachineState.toCheck:
return "To Check"; return "To Check";
case (FabAccessAPI.Schema.Machine.MachineState.reserved): case Machine.MachineState.reserved:
return "Reserved"; return "Reserved";
case (FabAccessAPI.Schema.Machine.MachineState.blocked): case Machine.MachineState.blocked:
return "Blocked"; return "Blocked";
case (FabAccessAPI.Schema.Machine.MachineState.disabled): case Machine.MachineState.disabled:
return "Disabled"; return "Disabled";
case Machine.MachineState.totakeover:
return "ToTakeOver";
default: default:
return "Unknown"; return "Unknown";
} }

View File

@ -1,45 +0,0 @@
using Plugin.Multilingual;
using System;
using System.Reflection;
using System.Resources;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.Helpers
{
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
const string _ResourceId = "Borepin.Resources.Text.TextResource";
static readonly Lazy<ResourceManager> _Resmgr = new Lazy<ResourceManager>(() => new ResourceManager(_ResourceId, typeof(TranslateExtension).GetTypeInfo().Assembly));
public string Text { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Text == null)
{
return "";
}
System.Globalization.CultureInfo ci = CrossMultilingual.Current.CurrentCultureInfo;
string translation = _Resmgr.Value.GetString(Text, ci);
if (translation == null)
{
#if DEBUG
//throw new ArgumentException(
// String.Format("Key '{0}' was not found in resources '{1}' for culture '{2}'.", Text, ResourceId, ci.Name),
// "Text");
translation = "!MISSING TEXT!";
#else
translation = Text; // returns the key, which GETS DISPLAYED TO THE USER
#endif
}
return translation;
}
}
}

View File

@ -1,7 +0,0 @@
namespace Borepin.Model
{
public enum AuthenticationTyp
{
PLAIN,
}
}

View File

@ -1,12 +0,0 @@
using System;
namespace Borepin.Model
{
public class BFFHInstance
{
public Uri Address { get; set; }
public string Name { get; set; } = "";
public string Description { get; set; } = "";
}
}

View File

@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
namespace Borepin.Model
{
/// <summary>
/// Class to contain all Information about a Connection
/// </summary>
public class Connection
{
#region Constructors
public Connection()
{
Address = new Uri("http://127.0.0.1:59661");
}
public Connection(Connection connection)
{
ConnectionTyp = connection.ConnectionTyp;
AuthenticationTyp = connection.AuthenticationTyp;
Address = connection.Address;
Username = connection.Username;
LastTime = connection.LastTime;
}
#endregion
#region Members
/// <summary>
/// Type of Connection
/// </summary>
public ConnectionTyp ConnectionTyp { get; set; } = ConnectionTyp.SINGLE;
/// <summary>
/// Type of Authentication
/// </summary>
public AuthenticationTyp AuthenticationTyp { get; set; } = AuthenticationTyp.PLAIN;
/// <summary>
/// Address to Host
/// </summary>
public Uri Address { get; set; }
/// <summary>
/// Username for Connection
/// </summary>
public string Username { get; set; } = "";
/// <summary>
/// Last Timestamp connection was successfully established
/// </summary>
public DateTime LastTime { get; set; }
#endregion
#region Methods
#region Equals and HashCode
public override bool Equals(object obj)
{
return obj is Connection connection &&
EqualityComparer<Uri>.Default.Equals(Address, connection.Address) &&
string.Equals(Username, connection.Username, StringComparison.Ordinal) &&
ConnectionTyp == connection.ConnectionTyp &&
AuthenticationTyp == connection.AuthenticationTyp;
}
public override int GetHashCode()
{
int hashCode = -904541792;
hashCode = hashCode * -1521134295 + EqualityComparer<Uri>.Default.GetHashCode(Address);
hashCode = hashCode * -1521134295 + LastTime.GetHashCode();
hashCode = hashCode * -1521134295 + StringComparer.Ordinal.GetHashCode(Username);
hashCode = hashCode * -1521134295 + ConnectionTyp.GetHashCode();
hashCode = hashCode * -1521134295 + AuthenticationTyp.GetHashCode();
return hashCode;
}
#endregion
#endregion
}
}

View File

@ -0,0 +1,53 @@
using FabAccessAPI;
using Prism.Mvvm;
namespace Borepin.Model
{
public class ConnectionDataVisualize : BindableBase
{
#region Private Fields
public readonly ConnectionData _ConnectionData;
#endregion
#region Constructors
public ConnectionDataVisualize(ConnectionData connectionData)
{
_ConnectionData = connectionData;
LoadData();
}
#endregion
#region Methods
public void LoadData()
{
Host = _ConnectionData.Host.Host;
Port = _ConnectionData.Host.Port;
Username = _ConnectionData.Username;
}
#endregion
#region Fields
private string _Host;
public string Host
{
get => _Host;
set => SetProperty(ref _Host, value);
}
private int _Port;
public int Port
{
get => _Port;
set => SetProperty(ref _Port, value);
}
private string _Username;
public string Username
{
get => _Username;
set => SetProperty(ref _Username, value);
}
#endregion
}
}

View File

@ -1,8 +0,0 @@
namespace Borepin.Model
{
public enum ConnectionTyp
{
SINGLE,
FEDERATED,
}
}

View File

@ -1,19 +0,0 @@
namespace Borepin.Model
{
public class Connection_Plain : Connection
{
#region Constructors
public Connection_Plain(Connection connection) : base(connection)
{
}
#endregion
#region Members
/// <summary>
/// Password for Connection
/// </summary>
public string Password { get; set; } = "";
#endregion
}
}

View File

@ -1,7 +0,0 @@
namespace Borepin.Model
{
public class ListItem
{
public string Value1 { get; set; }
}
}

View File

@ -73,6 +73,7 @@ namespace Borepin.Model
CanCheck = !((CheckInterface_Proxy)_Machine.Check).IsNull; CanCheck = !((CheckInterface_Proxy)_Machine.Check).IsNull;
CanManage = !((ManageInterface_Proxy)_Machine.Manage).IsNull; CanManage = !((ManageInterface_Proxy)_Machine.Manage).IsNull;
CanAdmin = !((AdminInterface_Proxy)_Machine.Admin).IsNull; CanAdmin = !((AdminInterface_Proxy)_Machine.Admin).IsNull;
CanNotUseByPermission = State == MachineState.free && CanUse == false;
} }
#endregion #endregion
@ -174,6 +175,13 @@ namespace Borepin.Model
get => _CanAdmin; get => _CanAdmin;
set => SetProperty(ref _CanAdmin, value); set => SetProperty(ref _CanAdmin, value);
} }
private bool _CanNotUseByPermission;
public bool CanNotUseByPermission
{
get => _CanNotUseByPermission;
set => SetProperty(ref _CanNotUseByPermission, value);
}
#endregion #endregion
} }
} }

View File

@ -1,76 +0,0 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Borepin.Service.Storage;
using Borepin.Service.Storage.Exceptions;
namespace Borepin.Model.Storage
{
/// <summary>
/// Store Credentials for Connection in SecureStorageService
/// </summary>
public class ConnectionCredentialStorage
{
#region Private Fields
private readonly ISecretStorageService _SecretStorageService;
#endregion
#region Constructors
public ConnectionCredentialStorage(ISecretStorageService secretService)
{
_SecretStorageService = secretService;
}
#endregion
#region Methods
/// <summary>
/// Get Password for Connection from SecureStorageService
/// </summary>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="MissingConnectionException"></exception>
public async Task<string> GetPassword(Connection connection)
{
if (connection.AuthenticationTyp != AuthenticationTyp.PLAIN)
{
throw new ArgumentException("AuthenticationTyp is not PLAIN", nameof(connection));
}
string password = await _SecretStorageService.GetAsync(string.Format(CultureInfo.InvariantCulture, "bffh_password_{0}_{1}", connection.Address.ToString(), connection.Username)).ConfigureAwait(false);
if (password == null)
{
throw new MissingConnectionException();
}
return password;
}
/// <summary>
/// Add Password for Connection to SecureStorageService
/// </summary>
public async Task AddCredentials(Connection connection, string password)
{
await _SecretStorageService.SetAsync(string.Format(CultureInfo.InvariantCulture, "bffh_password_{0}_{1}", connection.Address.ToString(), connection.Username), password).ConfigureAwait(false);
}
/// <summary>
/// Remove Password for Connection from SecureStorageService
/// </summary>
public Task RemoveCredentials(Connection connection)
{
_SecretStorageService.Remove(string.Format(CultureInfo.InvariantCulture, "bffh_password_{0}_{1}", connection.Address.ToString(), connection.Username));
return Task.CompletedTask;
}
/// <summary>
/// Remove all Connections from SecureStorage
/// </summary>
public Task RemoveAllCredentials()
{
_SecretStorageService.RemoveAll();
return Task.CompletedTask;
}
#endregion
}
}

View File

@ -1,135 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Borepin.Service.Storage;
using Borepin.Service.Storage.Exceptions;
using Newtonsoft.Json;
namespace Borepin.Model.Storage
{
/// <summary>
/// Store Connection in PreferenceStorageService
/// </summary>
public class ConnectionStorage
{
#region Private Fields
private readonly IPreferenceStorageService _PreferenceService;
#endregion
#region Constructors
public ConnectionStorage(IPreferenceStorageService preferenceService)
{
_PreferenceService = preferenceService;
}
#endregion
#region Methods
/// <summary>
/// Get Connection List from Storage
/// </summary>
/// <returns></returns>
public Task<IList<Connection>> GetConnectionList()
{
return Task.FromResult(_LoadConnectionFormStorage());
}
/// <summary>
/// Add Connection to Storage
/// </summary>
/// <exception cref="DuplicateConnectionException"></exception>
public Task<bool> AddConnection(Connection connection)
{
IList<Connection> connection_list = _LoadConnectionFormStorage();
if (connection_list.Contains(connection))
{
throw new DuplicateConnectionException();
}
connection_list.Add(connection);
_SaveConnectionToStorage(connection_list);
return Task.FromResult(true);
}
/// <summary>
/// Remove Connection from Storage
/// </summary>
public Task<bool> RemoveConnection(Connection connection)
{
IList<Connection> connection_list = _LoadConnectionFormStorage();
if (!connection_list.Contains(connection))
{
throw new MissingConnectionException();
}
while(connection_list.Contains(connection))
{
connection_list.Remove(connection);
}
_SaveConnectionToStorage(connection_list);
return Task.FromResult(true);
}
/// <summary>
/// Remove All Connection from Storage
/// </summary>
public Task<bool> RemoveAllConnections()
{
_SaveConnectionToStorage(new List<Connection>());
return Task.FromResult(true);
}
/// <summary>
/// Update Connections Timestamp in Storage
/// </summary>
/// <exception cref="MissingConnectionException"></exception>
public Task<bool> UpdateConnectionTimestamp(Connection connection)
{
IList<Connection> connection_list = _LoadConnectionFormStorage();
if (!connection_list.Contains(connection))
{
throw new MissingConnectionException();
}
int index = connection_list.IndexOf(connection);
Connection connection_update = connection_list[index];
connection_update.LastTime = DateTime.UtcNow;
connection_list[index] = connection_update;
_SaveConnectionToStorage(connection_list);
return Task.FromResult(true);
}
#endregion
#region Private Methodss
private IList<Connection> _LoadConnectionFormStorage()
{
List<Connection> connection_list;
try
{
connection_list = JsonConvert.DeserializeObject<List<Connection>>(_PreferenceService.Get("connection_list", "[]"));
}
catch (JsonSerializationException)
{
connection_list = new List<Connection>();
_PreferenceService.Set("connection_list", JsonConvert.SerializeObject(connection_list));
}
return connection_list;
}
private void _SaveConnectionToStorage(IList<Connection> connection_list)
{
_PreferenceService.Set("connection_list", JsonConvert.SerializeObject(connection_list));
}
#endregion
}
}

View File

@ -1,22 +0,0 @@
using System;
namespace Borepin.Model.Storage.Exceptions
{
public class MissingCredentialsException : Exception
{
public MissingCredentialsException()
{
}
public MissingCredentialsException(string message) : base(message)
{
}
public MissingCredentialsException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="de" original="BOREPIN/PROPERTIES/RESOURCES.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
<tool tool-id="MultilingualAppToolkit" tool-name="Multilingual App Toolkit" tool-version="4.0.6916.0" tool-company="Microsoft" />
</header>
<body>
<group id="BOREPIN/PROPERTIES/RESOURCES.RESX" datatype="resx" />
</body>
</file>
<file datatype="xml" source-language="en" target-language="de" original="BOREPIN/RESOURCES/TEXT/TEXTRESOURCE.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
<tool tool-id="MultilingualAppToolkit" tool-name="Multilingual App Toolkit" tool-version="4.0.6916.0" tool-company="Microsoft" />
</header>
<body>
<group id="BOREPIN/RESOURCES/TEXT/TEXTRESOURCE.RESX" datatype="resx">
<trans-unit id="SetUp_WelcomePage_Text" translate="yes" xml:space="preserve">
<source>Automate your Space with FabAccess</source>
<target state="new">Automate your Space with FabAccess</target>
</trans-unit>
<trans-unit id="SetUp_WelcomePage_Title" translate="yes" xml:space="preserve">
<source>Welcome</source>
<target state="new">Welcome</target>
</trans-unit>
<trans-unit id="SetUp_WelcomePage_Button" translate="yes" xml:space="preserve">
<source>Begin working</source>
<target state="new">Begin working</target>
</trans-unit>
<trans-unit id="SetUp_ScanPage_Button" translate="yes" xml:space="preserve">
<source>Login to your Space</source>
<target state="new">Login to your Space</target>
</trans-unit>
<trans-unit id="SetUp_ScanPage_Text" translate="yes" xml:space="preserve">
<source>Wenn du dieses Logo siehst, dann kannst du es scannen</source>
<target state="new">Wenn du dieses Logo siehst, dann kannst du es scannen</target>
</trans-unit>
</group>
</body>
</file>
</xliff>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="en" original="BOREPIN/PROPERTIES/RESOURCES.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
<tool tool-id="MultilingualAppToolkit" tool-name="Multilingual App Toolkit" tool-version="4.0.6916.0" tool-company="Microsoft" />
</header>
<body>
<group id="BOREPIN/PROPERTIES/RESOURCES.RESX" datatype="resx" />
</body>
</file>
<file datatype="xml" source-language="en" target-language="en" original="BOREPIN/RESOURCES/TEXT/TEXTRESOURCE.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
<tool tool-id="MultilingualAppToolkit" tool-name="Multilingual App Toolkit" tool-version="4.0.6916.0" tool-company="Microsoft" />
</header>
<body>
<group id="BOREPIN/RESOURCES/TEXT/TEXTRESOURCE.RESX" datatype="resx">
<trans-unit id="SetUp_WelcomePage_Text" translate="yes" xml:space="preserve">
<source>Automate your Space with FabAccess</source>
<target state="new">Automate your Space with FabAccess</target>
</trans-unit>
<trans-unit id="SetUp_WelcomePage_Title" translate="yes" xml:space="preserve">
<source>Welcome</source>
<target state="new">Welcome</target>
</trans-unit>
<trans-unit id="SetUp_WelcomePage_Button" translate="yes" xml:space="preserve">
<source>Begin working</source>
<target state="new">Begin working</target>
</trans-unit>
<trans-unit id="SetUp_ScanPage_Button" translate="yes" xml:space="preserve">
<source>Login to your Space</source>
<target state="new">Login to your Space</target>
</trans-unit>
<trans-unit id="SetUp_ScanPage_Text" translate="yes" xml:space="preserve">
<source>Wenn du dieses Logo siehst, dann kannst du es scannen</source>
<target state="new">Wenn du dieses Logo siehst, dann kannst du es scannen</target>
</trans-unit>
</group>
</body>
</file>
</xliff>

View File

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.AddServerProcess.AuthPlainPage" x:Class="Borepin.Page.AddServerProcess.AuthPlainPage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Connect to Server"> Title="Connect to Server">
<ContentPage.Resources> <ContentPage.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -15,13 +16,13 @@
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Username" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.USERNAME}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Entry Text="{Binding Username}" IsSpellCheckEnabled="false"/> <Entry Text="{Binding Username}" IsSpellCheckEnabled="false"/>
<Label Text="Password" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.PASSWORD}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Entry Text="{Binding Password}" IsPassword="True"/> <Entry Text="{Binding Password}" IsPassword="True"/>
<Button Text="Login" Command="{Binding AuthenticateCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.AddServerProcess_AuthPlainPage_Login}" Command="{Binding AuthenticateCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.AddServerProcess.ChooseAuthTypePage" x:Class="Borepin.Page.AddServerProcess.ChooseAuthTypePage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Connect to Server"> Title="Connect to Server">
<ContentPage.Resources> <ContentPage.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -15,13 +16,13 @@
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Sign In:" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_SignIn}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Button Text="Login with Password" Command="{Binding AuthPlainCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_LoginPassword}" Command="{Binding AuthPlainCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Label Text="or" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.OR}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Button Text="Login with Card" Style="{StaticResource Style_Button_Primary}" IsEnabled="False"/> <Button Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_LoginCard}" Style="{StaticResource Style_Button_Primary}" IsEnabled="False"/>
<Label Text="Sign Up:" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_SignUp}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Button Text="Register" Style="{StaticResource Style_Button_Primary}" IsEnabled="False"/> <Button Text="{x:Static resource_text:TextResource.AddServerProcess_ChooseAuthTypePage_Register}" Style="{StaticResource Style_Button_Primary}" IsEnabled="False"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.AddServerProcess.SelectServerPage" x:Class="Borepin.Page.AddServerProcess.SelectServerPage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Connect to Server"> Title="Connect to Server">
<ContentPage.Resources> <ContentPage.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -15,16 +16,17 @@
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Host" Style="{StaticResource Style_Label_Property_Title}"></Label> <Label Text="{x:Static resource_text:TextResource.HOST}" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Entry Text="{Binding Server}" Keyboard="Url" IsSpellCheckEnabled="false"/> <Entry Text="{Binding Host}" Keyboard="Url" IsSpellCheckEnabled="false"/>
<Button Text="Connect to Server" Command="{Binding ConnectToServerCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Connect}" Command="{Binding ConnectToServerCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="Scan QR-Code" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}"> <Button Text="{x:Static resource_text:TextResource.SCANQR}" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}">
<Button.IsVisible> <Button.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean" <OnPlatform x:TypeArguments="x:Boolean"
iOS="false" iOS="true"
Android="true"/> Android="true"/>
</Button.IsVisible> </Button.IsVisible>
</Button> </Button>
<Label Text="{x:Static resource_text:TextResource.AddServerProcess_SelectServerPage_Info}"></Label>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -4,6 +4,7 @@
xmlns:views="clr-namespace:Borepin.View" xmlns:views="clr-namespace:Borepin.View"
x:Class="Borepin.Page.MachineListPage" x:Class="Borepin.Page.MachineListPage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Machines"> Title="Machines">
<NavigationPage.TitleView> <NavigationPage.TitleView>
<Button Text="Refresh" HorizontalOptions="End" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}" Command="{Binding RefreshCommand}"/> <Button Text="Refresh" HorizontalOptions="End" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}" Command="{Binding RefreshCommand}"/>
@ -21,7 +22,7 @@
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<StackLayout IsVisible="{Binding IsConnected}"> <StackLayout IsVisible="{Binding IsConnected}">
<Button Text="Scan QR-Code" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}"> <Button Text="{x:Static resource_text:TextResource.SCANQR}" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}">
<Button.IsVisible> <Button.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean" <OnPlatform x:TypeArguments="x:Boolean"
iOS="True" iOS="True"
@ -39,7 +40,7 @@
</ListView> </ListView>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"> <StackLayout IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Please connect to Server" ></Label> <Label Text="{x:Static resource_text:TextResource.PLEASECONNECTTOSERVER}" ></Label>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>

View File

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.MachinePage" x:Class="Borepin.Page.MachinePage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Machine"> Title="Machine">
<NavigationPage.TitleView> <NavigationPage.TitleView>
<Label Text="{Binding MachineItem.State, Converter={StaticResource MachineStateStringConverter}}" FontAttributes="Bold" HorizontalOptions="End" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" WidthRequest="150" Margin="7.5" VerticalOptions="FillAndExpand" FontSize="Small" BackgroundColor="{Binding MachineItem.State, Converter={StaticResource MachineStateColorConverter}}"/> <Label Text="{Binding MachineItem.State, Converter={StaticResource MachineStateStringConverter}}" FontAttributes="Bold" HorizontalOptions="End" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" WidthRequest="150" Margin="7.5" VerticalOptions="FillAndExpand" FontSize="Small" BackgroundColor="{Binding MachineItem.State, Converter={StaticResource MachineStateColorConverter}}"/>
@ -25,25 +26,28 @@
<Label Text="{Binding MachineItem.Name}" Style="{StaticResource LabelStyle_Title}"/> <Label Text="{Binding MachineItem.Name}" Style="{StaticResource LabelStyle_Title}"/>
<Label Text="{Binding MachineItem.Description}" Style="{StaticResource Style_Label_Text_Center}"/> <Label Text="{Binding MachineItem.Description}" Style="{StaticResource Style_Label_Text_Center}"/>
<StackLayout IsVisible="{Binding MachineItem.CanUse}"> <StackLayout IsVisible="{Binding MachineItem.CanUse}">
<Button Text="Use" Command="{Binding UseMachineCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_Use}" Command="{Binding UseMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CanNotUseByPermission}">
<Label Text="{x:Static resource_text:TextResource.MachinePage_CanNotUseByPermission}" Style="{StaticResource Style_Label_Text_Center}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CanInUse}"> <StackLayout IsVisible="{Binding MachineItem.CanInUse}">
<Button Text="GiveBack" Command="{Binding GiveBackMachineCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_GiveBack}" Command="{Binding GiveBackMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CurrentUser, Converter={StaticResource IsNotNullBoolConverter}}"> <StackLayout IsVisible="{Binding MachineItem.CurrentUser, Converter={StaticResource IsNotNullBoolConverter}}">
<Label Text="Current User:" Style="{StaticResource Style_Label_Property_Title}"/> <Label Text="{x:Static resource_text:TextResource.MachinePage_CurrentUser}" Style="{StaticResource Style_Label_Property_Title}"/>
<Label Text="{Binding MachineItem.CurrentUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/> <Label Text="{Binding MachineItem.CurrentUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding MachineItem.LastUser, Converter={StaticResource IsNotNullBoolConverter}}"> <StackLayout IsVisible="{Binding MachineItem.LastUser, Converter={StaticResource IsNotNullBoolConverter}}">
<Label Text="Last User:" Style="{StaticResource Style_Label_Property_Title}"/> <Label Text="{x:Static resource_text:TextResource.MachinePage_LastUser}" Style="{StaticResource Style_Label_Property_Title}"/>
<Label Text="{Binding MachineItem.LastUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/> <Label Text="{Binding MachineItem.LastUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CanManage}"> <StackLayout IsVisible="{Binding MachineItem.CanManage}">
<Label Text="Manage Machine:" Style="{StaticResource Style_Label_Property_Title}"/> <Label Text="{x:Static resource_text:TextResource.MachinePage_ManageMachine}" Style="{StaticResource Style_Label_Property_Title}"/>
<Button Text="Force Free" Command="{Binding ForceFreeMachineCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.MachinePage_ForceFree}" Command="{Binding ForceFreeMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
<Label Text="Please connect to Server" IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"></Label> <Label Text="{x:Static resource_text:TextResource.PLEASECONNECTTOSERVER}" IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"></Label>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -2,13 +2,15 @@
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms" <FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.MainPage" x:Class="Borepin.Page.MainPage"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="MainPage"> Title="MainPage">
<FlyoutPage.Flyout> <FlyoutPage.Flyout>
<ContentPage Title="FabAccess" BackgroundColor="{StaticResource SecondColor}"> <ContentPage Title="FabAccess" BackgroundColor="{StaticResource SecondColor}">
<StackLayout> <StackLayout>
<StackLayout Margin="0,50,0,0" VerticalOptions="FillAndExpand"> <StackLayout Margin="0,50,0,0" VerticalOptions="FillAndExpand">
<Button Text="Machines" Command="{Binding NavigateCommand}" CommandParameter="MachineListPage" VerticalOptions="Start" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}"/> <Button Text="{x:Static resource_text:TextResource.MainPage_Machines}" Command="{Binding NavigateCommand}" CommandParameter="MachineListPage" VerticalOptions="Start" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}"/>
<Button Text="Servers" Command="{Binding NavigateCommand}" CommandParameter="ServerListPage" VerticalOptions="Start" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}"/> <Button Text="{x:Static resource_text:TextResource.MainPage_Users}" IsVisible="{Binding CanManageUsers}" Command="{Binding NavigateCommand}" CommandParameter="UserListPage" VerticalOptions="Start" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}"/>
<Button Text="{x:Static resource_text:TextResource.MainPage_Servers}" Command="{Binding NavigateCommand}" CommandParameter="ServerListPage" VerticalOptions="Start" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}"/>
</StackLayout> </StackLayout>
<StackLayout Margin="0,0,0,10"> <StackLayout Margin="0,0,0,10">
<Label Text="{Binding CurrentVersion, StringFormat='Version: {0}'}" VerticalOptions="End" Margin="10,0,0,0" TextColor="{StaticResource FirstColor}"/> <Label Text="{Binding CurrentVersion, StringFormat='Version: {0}'}" VerticalOptions="End" Margin="10,0,0,0" TextColor="{StaticResource FirstColor}"/>

View File

@ -2,11 +2,12 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms" xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
x:Class="Borepin.Page.ScanPage"> x:Class="Borepin.Page.ScanPage">
<ContentPage.Content> <ContentPage.Content>
<StackLayout IsVisible="{Binding IsVisible}"> <StackLayout IsVisible="{Binding IsVisible}">
<zxing:ZXingScannerView Result="{Binding ScanResult, Mode=TwoWay}" ScanResultCommand="{Binding ScannedCommand}" IsScanning="{Binding IsScanning}" WidthRequest="300" HeightRequest="500" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" Options="{Binding ScanOptions}"/> <zxing:ZXingScannerView Result="{Binding ScanResult, Mode=TwoWay}" ScanResultCommand="{Binding ScannedCommand}" IsScanning="{Binding IsScanning}" WidthRequest="300" HeightRequest="500" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" Options="{Binding ScanOptions}"/>
<Button Text="Abort" Command="{Binding AbortCommand}"/> <Button Text="{x:Static resource_text:TextResource.CANCEL}" Command="{Binding CancelCommand}"/>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>
</ContentPage> </ContentPage>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
x:Class="Borepin.Page.ScanURNPage">
<ContentPage.Content>
<StackLayout IsVisible="{Binding IsVisible}">
<zxing:ZXingScannerView Result="{Binding ScanResult, Mode=TwoWay}" ScanResultCommand="{Binding ScannedCommand}" IsScanning="{Binding IsScanning}" WidthRequest="300" HeightRequest="500" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" Options="{Binding ScanOptions}"/>
<Button Text="{x:Static resource_text:TextResource.CANCEL}" Command="{Binding CancelCommand}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.Page
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ScanURNPage : ContentPage
{
public ScanURNPage()
{
InitializeComponent();
}
}
}

View File

@ -4,6 +4,7 @@
xmlns:views="clr-namespace:Borepin.View" xmlns:views="clr-namespace:Borepin.View"
x:Class="Borepin.Page.ServerListPage" x:Class="Borepin.Page.ServerListPage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Servers"> Title="Servers">
<ContentPage.Resources> <ContentPage.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -17,11 +18,11 @@
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout> </StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}" VerticalOptions="FillAndExpand"> <StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}" VerticalOptions="FillAndExpand">
<Label Text="Active Connection" IsVisible="{Binding HasActiveConnection}"/> <Label Text="{x:Static resource_text:TextResource.ServerListPage_ActiveConnection}" IsVisible="{Binding HasActiveConnection}"/>
<StackLayout IsVisible="{Binding HasActiveConnection}"> <StackLayout IsVisible="{Binding HasActiveConnection}">
<views:ServerListItemView BindingContext="{Binding ActiveConnection}" MinimumHeightRequest="50"/> <views:ServerListItemView BindingContext="{Binding ActiveConnection}" MinimumHeightRequest="50"/>
</StackLayout> </StackLayout>
<Label Text="Last Connections" IsVisible="{Binding ServerListItemViewModel_List, Converter={StaticResource ListNotEmptyConverter}}"/> <Label Text="{x:Static resource_text:TextResource.ServerListPage_LastConnection}" IsVisible="{Binding ServerListItemViewModel_List, Converter={StaticResource ListNotEmptyConverter}}"/>
<ListView ItemsSource="{Binding ServerListItemViewModel_List}" SelectionMode="None" SeparatorColor="Transparent" VerticalOptions="StartAndExpand"> <ListView ItemsSource="{Binding ServerListItemViewModel_List}" SelectionMode="None" SeparatorColor="Transparent" VerticalOptions="StartAndExpand">
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate> <DataTemplate>
@ -31,7 +32,7 @@
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
</ListView> </ListView>
<Button Text="Connect to new Server" Command="{Binding AddInstancesCommand}" Style="{StaticResource Style_Button_Primary}" VerticalOptions="End"/> <Button Text="{x:Static resource_text:TextResource.ServerListPage_ConnectToNewServer}" Command="{Binding AddInstancesCommand}" Style="{StaticResource Style_Button_Primary}" VerticalOptions="End"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -3,6 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.ServerPage" x:Class="Borepin.Page.ServerPage"
xmlns:converters="clr-namespace:Borepin.Converter" xmlns:converters="clr-namespace:Borepin.Converter"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Server"> Title="Server">
<ContentPage.Resources> <ContentPage.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -22,10 +23,12 @@
<StackLayout Grid.Row="0"> <StackLayout Grid.Row="0">
<Label Text="{Binding DisplayAddress}" Style="{StaticResource LabelStyle_Title}"/> <Label Text="{Binding DisplayAddress}" Style="{StaticResource LabelStyle_Title}"/>
<Label Text="{Binding Connection_Item.Username}" Style="{StaticResource Style_Label_Text_Center}"/> <Label Text="{Binding Connection_Item.Username}" Style="{StaticResource Style_Label_Text_Center}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection, Converter={StaticResource InvertBoolConverter}}" Text="Connect" Margin="0,10,0,0" Command="{Binding ConnectCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button IsVisible="{Binding InstanceIsDefaultConnection, Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_SetDefault}" Margin="0,10,0,0" Command="{Binding SetDefaultCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection}" Text="Disconnect" Margin="0,10,0,0" Command="{Binding DisconnectCommand}" Style="{StaticResource Style_Button_Admin}"/> <Label IsVisible="{Binding InstanceIsDefaultConnection}" Text="{x:Static resource_text:TextResource.ServerPage_IsDefault}" Style="{StaticResource Style_Label_Text_Center}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection, Converter={StaticResource InvertBoolConverter}}" Text="{x:Static resource_text:TextResource.ServerPage_Connect}" Margin="0,10,0,0" Command="{Binding ConnectCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection}" Text="{x:Static resource_text:TextResource.ServerPage_Disconnect}" Margin="0,10,0,0" Command="{Binding DisconnectCommand}" Style="{StaticResource Style_Button_Admin}"/>
</StackLayout> </StackLayout>
<Button Grid.Row="1" Text="Delete" Command="{Binding DeleteCommand}" Style="{StaticResource Style_Button_Admin}" VerticalOptions="End"/> <Button Grid.Row="1" Text="{x:Static resource_text:TextResource.DELETE}" Command="{Binding DeleteCommand}" Style="{StaticResource Style_Button_Admin}" VerticalOptions="End"/>
</Grid> </Grid>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>

View File

@ -2,14 +2,14 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.SetUpProcess.WelcomePage" x:Class="Borepin.Page.SetUpProcess.WelcomePage"
xmlns:i18n="clr-namespace:Borepin.Helpers" xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="FabAccess"> Title="FabAccess">
<ContentPage.Content> <ContentPage.Content>
<ScrollView> <ScrollView>
<StackLayout Style="{StaticResource Style_StackLayout_Content}"> <StackLayout Style="{StaticResource Style_StackLayout_Content}">
<Label Text="{i18n:Translate SetUp_WelcomePage_Title}" Style="{StaticResource Style_Label_Title_Center}"/> <Label Text="{x:Static resource_text:TextResource.SetUpProcess_WelcomePage_Title}" Style="{StaticResource Style_Label_Title_Center}"/>
<Label Text="{i18n:Translate SetUp_WelcomePage_Text}" Style="{StaticResource Style_Label_Text_Center}"/> <Label Text="{x:Static resource_text:TextResource.SetUpProcess_WelcomePage_Text}" Style="{StaticResource Style_Label_Text_Center}"/>
<Button Text="{i18n:Translate SetUp_WelcomePage_Button}" Command="{Binding NextCommand}" Style="{StaticResource Style_Button_Primary}"/> <Button Text="{x:Static resource_text:TextResource.SetUpProcess_WelcomePage_Button}" Command="{Binding NextCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout> </StackLayout>
</ScrollView> </ScrollView>
</ContentPage.Content> </ContentPage.Content>

View File

@ -2,10 +2,19 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.StartPage" x:Class="Borepin.Page.StartPage"
xmlns:resource_text="clr-namespace:Borepin.Resources.Text"
Title="Start"> Title="Start">
<ContentPage.Content> <ContentPage.Content>
<StackLayout Padding="20"> <StackLayout Padding="20">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator> <StackLayout IsVisible="{Binding IsBusy}" VerticalOptions="CenterAndExpand">
<Label Text="{x:Static resource_text:TextResource.StartPage_Starting}" Style="{StaticResource Style_Label_Text_Center}"/>
<ActivityIndicator IsRunning="{Binding IsBusy}"/>
</StackLayout>
<ActivityIndicator IsRunning="{Binding IsBusy}"/>
<StackLayout IsVisible="{Binding IsConnecting}" VerticalOptions="CenterAndExpand">
<Label Text="{x:Static resource_text:TextResource.StartPage_Connecting}" Style="{StaticResource Style_Label_Text_Center}"/>
<ActivityIndicator IsRunning="{Binding IsConnecting}"/>
</StackLayout>
</StackLayout> </StackLayout>
</ContentPage.Content> </ContentPage.Content>
</ContentPage> </ContentPage>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Borepin.View"
x:Class="Borepin.Page.UserListPage"
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Machines">
<NavigationPage.TitleView>
<Button Text="Refresh" HorizontalOptions="End" BackgroundColor="{StaticResource SecondColor}" TextColor="{StaticResource FirstColor}" Command="{Binding RefreshCommand}"/>
</NavigationPage.TitleView>
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
<converters:ListNotEmptyConverter x:Key="ListNotEmptyConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<StackLayout IsVisible="{Binding IsConnected}">
<ListView ItemsSource="{Binding UserListItemViewModel_List}" SelectionMode="None" SeparatorColor="Transparent">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<views:UserListItemView />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Please connect to Server" ></Label>
</StackLayout>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -0,0 +1,15 @@

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.Page
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class UserListPage : ContentPage
{
public UserListPage()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.UserPage"
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Machine">
<ContentPage.Resources>
<ResourceDictionary>
<converters:MachineStateColorConverter x:Key="MachineStateColorConverter"/>
<converters:MachineStateStringConverter x:Key="MachineStateStringConverter"/>
<converters:IsNotNullBoolConverter x:Key="IsNotNullBoolConverter"/>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<StackLayout IsVisible="{Binding IsConnected}">
<Label Text="{Binding UserItem.Username}" Style="{StaticResource LabelStyle_Title}"/>
</StackLayout>
<Label Text="Please connect to Server" IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"></Label>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -0,0 +1,15 @@

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.Page
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class UserPage : ContentPage
{
public UserPage()
{
InitializeComponent();
}
}
}

View File

@ -1,42 +1,49 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Base.Exceptions;
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions; using Borepin.Service.Storage;
using FabAccessAPI;
using FabAccessAPI.Exceptions; using FabAccessAPI.Exceptions;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess namespace Borepin.PageModel.AddServerProcess
{ {
public class AuthPlainPageModel : PageModelBase public class AuthPlainPageModel : ConnectionModelBase
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private ConnectionData _ConnectionData;
private readonly IPageDialogService _PageDialogService; private readonly ILoginStorageService _LoginStorageService;
private Connection _Connection;
#endregion #endregion
#region Constructors #region Constructors
public AuthPlainPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService) public AuthPlainPageModel(INavigationService navigationService, IAPIService apiService, IPageDialogService pageDialogService, ILoginStorageService loginStorageService) : base(navigationService, pageDialogService, apiService)
{ {
_BFFHService = bffhService; _LoginStorageService = loginStorageService;
_PageDialogService = pageDialogService;
AuthenticateCommand = new DelegateCommand(async () => await AuthenticateCommandExecute().ConfigureAwait(false)); AuthenticateCommand = new DelegateCommand(async () => await AuthenticateCommandExecute().ConfigureAwait(false));
} }
#endregion #endregion
#region LoadData #region LoadData
public override Task LoadData() public override Task LoadInstance(object instance)
{ {
Username = _Connection.Username; if(instance is ConnectionData)
{
IsBusy = false; _ConnectionData = instance as ConnectionData;
Username = _ConnectionData.Username;
}
else
{
throw new InstanceIncorrectException();
}
return Task.CompletedTask; return Task.CompletedTask;
} }
#endregion #endregion
@ -68,64 +75,73 @@ namespace Borepin.PageModel.AddServerProcess
{ {
IsBusy = true; IsBusy = true;
_Connection.Username = Username; _ConnectionData = new ConnectionData()
if (_BFFHService.IsConnected)
{ {
await _BFFHService.Disconnect().ConfigureAwait(true); Host = _ConnectionData.Host,
Mechanism = Mechanism.PLAIN,
Username = Username,
Properties = new Dictionary<string, object>(StringComparer.Ordinal)
{
{ "Username", Username },
{ "Password", Password },
},
};
if (_API.IsConnected)
{
if (_API.IsConnected)
{
await _API.Disconnect().ConfigureAwait(true);
_API.UnbindAllEvents();
}
} }
try try
{ {
await _BFFHService.Connect(_Connection, Password).ConfigureAwait(true); await _API.Connect(_ConnectionData).ConfigureAwait(false);
} }
catch (ConnectingFailedException) catch (ConnectingFailedException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
IsBusy = false; IsBusy = false;
});
return; return;
} }
catch (AuthenticationFailedException) catch (AuthenticationFailedException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false);
IsBusy = false; IsBusy = false;
});
return; return;
} }
catch(Exception) catch(Exception)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unexpected Error.", "Ok").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unexpected Error.", "Ok").ConfigureAwait(false);
IsBusy = false; IsBusy = false;
});
return; return;
} }
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false); await _LoginStorageService.Add(_ConnectionData).ConfigureAwait(false);
} await _LoginStorageService.UpdateTimestamp(_ConnectionData).ConfigureAwait(false);
#endregion
#region INavigationAware Device.BeginInvokeOnMainThread(async () =>
public override void OnNavigatedTo(INavigationParameters parameters)
{
if (parameters.ContainsKey("instance") && parameters["instance"] is Connection)
{ {
_Connection = parameters["instance"] as Connection; INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
} if (result.Exception != null)
else {
{ Log.Fatal(result.Exception, "Navigating failed");
_Connection = new Connection(); }
} });
LoadData();
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
if(parameters.GetNavigationMode() == NavigationMode.Back)
{
parameters.Add("instance", _Connection);
}
} }
#endregion #endregion
} }

View File

@ -1,6 +1,8 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Base.Exceptions;
using FabAccessAPI;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms; using Xamarin.Forms;
@ -10,23 +12,34 @@ namespace Borepin.PageModel.AddServerProcess
public class ChooseAuthTypePageModel : PageModelBase public class ChooseAuthTypePageModel : PageModelBase
{ {
#region Private Fields #region Private Fields
private Connection _Connection; private ConnectionData _ConnectionData;
#endregion #endregion
#region Contructors #region Contructors
public ChooseAuthTypePageModel(INavigationService navigationService) : base(navigationService) public ChooseAuthTypePageModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{ {
AuthPlainCommand = new Command(AuthPlainCommandExecute); AuthPlainCommand = new Command(AuthPlainCommandExecute);
} }
#endregion #endregion
#region LoadData #region LoadData
public override Task LoadData() public override Task LoadInstance(object instance)
{ {
IsBusy = false; if(instance is ConnectionData)
{
_ConnectionData = instance as ConnectionData;
}
else
{
throw new InstanceIncorrectException();
}
return Task.CompletedTask; return Task.CompletedTask;
} }
public override Task<object> CreateInstance()
{
return Task.FromResult<object>(_ConnectionData);
}
#endregion #endregion
#region Commands #region Commands
@ -38,37 +51,12 @@ namespace Borepin.PageModel.AddServerProcess
} }
public async void AuthPlainCommandExecute() public async void AuthPlainCommandExecute()
{ {
_Connection.AuthenticationTyp = AuthenticationTyp.PLAIN; _ConnectionData.Mechanism = Mechanism.PLAIN;
INavigationParameters parameters = new NavigationParameters() INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_AuthPlainPage").ConfigureAwait(false);
if(result.Exception != null)
{ {
{"instance", _Connection }, Log.Fatal(result.Exception, "Navigating failed");
};
await _NavigationService.NavigateAsync("AddServerProcess_AuthPlainPage", parameters).ConfigureAwait(false);
}
#endregion
#region INavigationAware
public override void OnNavigatedTo(INavigationParameters parameters)
{
if (parameters.ContainsKey("instance") && parameters["instance"] is Connection)
{
_Connection = parameters["instance"] as Connection;
}
else
{
_Connection = new Connection();
}
LoadData();
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
if (parameters.GetNavigationMode() == NavigationMode.Back)
{
parameters.Add("instance", _Connection);
} }
} }
#endregion #endregion

View File

@ -1,12 +1,10 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using FabAccessAPI;
using Borepin.Service.BFFH; using FabAccessAPI.Exceptions;
using Prism.AppModel; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
using Prism.Services.Dialogs;
using System; using System;
using System.Globalization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
@ -14,46 +12,55 @@ using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess namespace Borepin.PageModel.AddServerProcess
{ {
public class SelectServerPageModel : PageModelBase, IPageLifecycleAware public class SelectServerPageModel : PageModelBase
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private ConnectionData _ConnectionData;
private readonly IPageDialogService _PageDialogService;
private readonly IDialogService _DialogService;
private Connection _Connection;
private bool _Scanned;
#endregion #endregion
#region Constructors #region Constructors
public SelectServerPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService, IDialogService dialogService) : base(navigationService) public SelectServerPageModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{ {
_BFFHService = bffhService; ConnectToServerCommand = new DelegateCommand(async () => await ConnectToServerExecute().ConfigureAwait(false));
_PageDialogService = pageDialogService; DetectLocalServerCommand = new DelegateCommand(DetectHostCommandExecute);
_DialogService = dialogService; ScanCodeCommand = new DelegateCommand(ScanCodeCommandExecute);
ConnectToServerCommand = new Command(async ()=> await ConnectToServerExecute().ConfigureAwait(false));
DetectLocalServerCommand = new Command(DetectHostCommandExecute);
ScanCodeCommand = new Command(ScanCodeCommandExecute);
} }
#endregion #endregion
#region LoadData #region LoadData
public override Task LoadData() public override Task LoadInstance(object instance)
{ {
Server = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", _Connection.Address.Host, _Connection.Address.Port); if(instance is ConnectionData)
{
_ConnectionData = instance as ConnectionData;
Host = _ConnectionData.Host.ToString();
}
IsBusy = false;
return Task.CompletedTask; return Task.CompletedTask;
} }
public override Task LoadFromParameters(INavigationParameters parameters)
{
if(parameters.ContainsKey("result") && string.Equals((string)parameters["result"], "scanned", StringComparison.Ordinal) && parameters.ContainsKey("value"))
{
Host = (string)parameters["value"];
}
return Task.CompletedTask;
}
public override Task<object> CreateInstance()
{
return Task.FromResult<object>(_ConnectionData);
}
#endregion #endregion
#region Fields #region Fields
private string _Server; private string _Host;
public string Server public string Host
{ {
get => _Server; get => _Host;
set => SetProperty(ref _Server, value); set => SetProperty(ref _Host, value);
} }
#endregion #endregion
@ -66,18 +73,23 @@ namespace Borepin.PageModel.AddServerProcess
} }
public async Task ConnectToServerExecute() public async Task ConnectToServerExecute()
{ {
if (Host == "" || Host == null)
{
return;
}
IsBusy = true; IsBusy = true;
try try
{ {
string server_address = ""; string server_address = "";
if(Regex.IsMatch(Server, "([a-zA-Z]{2,20}):\\/\\/", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1))) if(Regex.IsMatch(Host, "([a-zA-Z]{2,20}):\\/\\/", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1)))
{ {
server_address = Server; server_address = Host;
} }
else else
{ {
server_address = "http://" + Server; server_address = "http://" + Host;
} }
UriBuilder builder = new UriBuilder(server_address); UriBuilder builder = new UriBuilder(server_address);
@ -86,33 +98,48 @@ namespace Borepin.PageModel.AddServerProcess
builder.Port = 59661; builder.Port = 59661;
} }
_Connection = new Connection() _ConnectionData = new ConnectionData()
{ {
Address = builder.Uri, Host = builder.Uri,
}; };
} }
catch (UriFormatException) catch (UriFormatException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Server address is invaild.", "Ok").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Server address is invaild.", "Ok").ConfigureAwait(false);
IsBusy = false;
});
IsBusy = false;
return; return;
} }
if (!await _BFFHService.TestConnection(_Connection).ConfigureAwait(true)) try
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false); API api = new API();
await api.TestConnection(_ConnectionData).ConfigureAwait(false);
}
catch(ConnectingFailedException)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
});
IsBusy = false;
return; return;
} }
INavigationParameters parameters = new NavigationParameters() Device.BeginInvokeOnMainThread(async () =>
{ {
{"instance", _Connection }, INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage").ConfigureAwait(false);
}; if (result.Exception != null)
{
await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage", parameters).ConfigureAwait(false); Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
private ICommand _ScanCodeCommand; private ICommand _ScanCodeCommand;
@ -123,16 +150,14 @@ namespace Borepin.PageModel.AddServerProcess
} }
public void ScanCodeCommandExecute() public void ScanCodeCommandExecute()
{ {
_DialogService.ShowDialog("ScanDialog", ScanCodeCommandExecute_Dialog); Device.BeginInvokeOnMainThread(async () =>
}
public void ScanCodeCommandExecute_Dialog(IDialogResult result)
{
if (string.Equals(result.Parameters.GetValue<string>("result"), "scanned", StringComparison.Ordinal))
{ {
Server = result.Parameters["value"] as string; INavigationResult result = await _NavigationService.NavigateAsync("ScanPage").ConfigureAwait(false);
_Scanned = true; if (result.Exception != null)
} {
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
private ICommand _DetectLocalServerCommand; private ICommand _DetectLocalServerCommand;
@ -144,52 +169,7 @@ namespace Borepin.PageModel.AddServerProcess
public void DetectHostCommandExecute() public void DetectHostCommandExecute()
{ {
// Get Example Server Address // Get Example Server Address
Server = "127.0.0.1:59661"; Host = "127.0.0.1:59661";
}
#endregion
#region IPageLifecycleAware
public async void OnAppearing()
{
if (_Scanned)
{
_Scanned = false;
await ConnectToServerExecute().ConfigureAwait(false);
}
}
public void OnDisappearing()
{
}
#endregion
#region INavigationAware
public override void OnNavigatedTo(INavigationParameters parameters)
{
if(_Connection == null)
{
if (parameters.ContainsKey("instance") && parameters["instance"] is Connection)
{
_Connection = parameters["instance"] as Connection;
}
else
{
_Connection = new Connection();
}
LoadData();
}
else
{
IsBusy = false;
}
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
} }
#endregion #endregion
} }

View File

@ -4,50 +4,33 @@ using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Borepin.Service.BFFH;
using Borepin.Base; using Borepin.Base;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using Prism.Services; using Prism.Services;
using static FabAccessAPI.Schema.Machine;
using System; using System;
using NaturalSort.Extension; using NaturalSort.Extension;
using System.Linq; using System.Linq;
using Borepin.Service;
using static FabAccessAPI.Schema.Machine;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class MachineListPageModel : ConnectionModelBase public class MachineListPageModel : ConnectionModelBase
{ {
#region Private Fields
private Machine _NextMachine;
#endregion
#region Constructors #region Constructors
public MachineListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bFFHService) : base(navigationService, pageDialogService, bFFHService) public MachineListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute);
ScanCodeCommand = new DelegateCommand(async () => await ScanCodeCommandExecute().ConfigureAwait(false)); ScanCodeCommand = new DelegateCommand(async () => await ScanCodeCommandExecute().ConfigureAwait(false));
RefreshCommand = new DelegateCommand(async ()=> await RefreshCommandExecute().ConfigureAwait(true)); RefreshCommand = new DelegateCommand(async ()=> await RefreshCommandExecute().ConfigureAwait(true));
} }
#endregion #endregion
#region Data #region Data
public override async Task LoadData() public override async Task LoadAPIData()
{ {
if (! await CheckConnection().ConfigureAwait(false)) User user_self = await _API.Session.UserSystem.Info.GetUserSelf().ConfigureAwait(false);
{
IsConnected = false;
IsBusy = false; IReadOnlyList<Machine> machine_list = await _API.Session.MachineSystem.Info.GetMachineList().ConfigureAwait(false);
return;
}
IsConnected = true;
MachineSystem machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
UserSystem userSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).UserSystem;
User user_self = await userSystem.Info.GetUserSelf().ConfigureAwait(false);
IReadOnlyList<Machine> machine_list = await machineSystem.Info.GetMachineList().ConfigureAwait(false);
List<MachineListItemViewModel> viewmodel_list_user_assigned = new List<MachineListItemViewModel>(); List<MachineListItemViewModel> viewmodel_list_user_assigned = new List<MachineListItemViewModel>();
List<MachineListItemViewModel> viewmodel_list_not_user_assigned = new List<MachineListItemViewModel>(); List<MachineListItemViewModel> viewmodel_list_not_user_assigned = new List<MachineListItemViewModel>();
@ -55,24 +38,25 @@ namespace Borepin.PageModel
{ {
if(!((InUseInterface_Proxy)machine.Inuse).IsNull) if(!((InUseInterface_Proxy)machine.Inuse).IsNull)
{ {
MachineListItemViewModel new_viewmodel = new MachineListItemViewModel(machine) MachineListItemViewModel new_viewmodel = new MachineListItemViewModel(_NavigationService, _PageDialogService)
{ {
IsUserAssigned = true, IsInUseByMe = true,
}; };
await new_viewmodel.LoadInstance(machine).ConfigureAwait(false);
viewmodel_list_user_assigned.Add(new_viewmodel); viewmodel_list_user_assigned.Add(new_viewmodel);
} }
else else
{ {
viewmodel_list_not_user_assigned.Add(new MachineListItemViewModel(machine)); MachineListItemViewModel new_viewmodel = new MachineListItemViewModel(_NavigationService, _PageDialogService);
await new_viewmodel.LoadInstance(machine).ConfigureAwait(false);
viewmodel_list_not_user_assigned.Add(new_viewmodel);
} }
} }
List<MachineListItemViewModel> viewmodel_list_sorted = new List<MachineListItemViewModel>(); List<MachineListItemViewModel> viewmodel_list_sorted = new List<MachineListItemViewModel>();
viewmodel_list_sorted.AddRange(viewmodel_list_user_assigned.OrderBy(x => x.Name, StringComparison.OrdinalIgnoreCase.WithNaturalSort())); viewmodel_list_sorted.AddRange(viewmodel_list_user_assigned.OrderBy(x => x.Machine.Name, StringComparison.OrdinalIgnoreCase.WithNaturalSort()));
viewmodel_list_sorted.AddRange(viewmodel_list_not_user_assigned.OrderBy(x => x.Name, StringComparison.OrdinalIgnoreCase.WithNaturalSort())); viewmodel_list_sorted.AddRange(viewmodel_list_not_user_assigned.OrderBy(x => x.Machine.Name, StringComparison.OrdinalIgnoreCase.WithNaturalSort()));
MachineListItemViewModel_List = viewmodel_list_sorted; MachineListItemViewModel_List = viewmodel_list_sorted;
IsBusy = false;
} }
#endregion #endregion
@ -101,26 +85,12 @@ namespace Borepin.PageModel
} }
public async Task RefreshCommandExecute() public async Task RefreshCommandExecute()
{ {
await LoadData().ConfigureAwait(true); if(_API.IsConnected)
IsRefreshing = false;
}
private ICommand _SelectInstanceCommand;
public ICommand SelectInstanceCommand
{
get => _SelectInstanceCommand;
set => SetProperty(ref _SelectInstanceCommand, value);
}
public async void SelectInstanceCommandExecute(object obj)
{
MachineListItemViewModel viewmodel = obj as MachineListItemViewModel;
NavigationParameters parameters = new NavigationParameters
{ {
{ "id", viewmodel.Instance.Id }, await LoadAPIData().ConfigureAwait(true);
}; }
await _NavigationService.NavigateAsync($"MachinePage", parameters).ConfigureAwait(false); IsRefreshing = false;
} }
private ICommand _ScanCodeCommand; private ICommand _ScanCodeCommand;
@ -138,66 +108,7 @@ namespace Borepin.PageModel
{"intance", null }, {"intance", null },
}; };
await _NavigationService.NavigateAsync("ScanPage", parameters).ConfigureAwait(false); await _NavigationService.NavigateAsync("ScanURNPage", parameters).ConfigureAwait(false);
}
public async void ScanCode_Result(string value)
{
if (! _BFFHService.IsConnected)
{
IsConnected = false;
IsBusy = false;
return;
}
MachineSystem machineInterface = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
Machine machine = (await machineInterface.Info.GetMachineURN(value).ConfigureAwait(false)).Just;
if(machine == null)
{
IsBusy = false;
return;
}
_NextMachine = machine;
IsBusy = false;
}
#endregion
#region IPageLifecycleAware
public async void OnAppearing()
{
if(_NextMachine != null)
{
NavigationParameters parameters = new NavigationParameters
{
{ "id", _NextMachine.Id},
};
_NextMachine = null;
await _NavigationService.NavigateAsync("MachinePage", parameters).ConfigureAwait(false);
}
}
public void OnDisappearing()
{
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
IsBusy = true;
await LoadData().ConfigureAwait(false);
} }
#endregion #endregion
} }

View File

@ -4,11 +4,12 @@ using Prism.Navigation;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using Borepin.Service.BFFH;
using static FabAccessAPI.Schema.MachineSystem;
using Borepin.Model; using Borepin.Model;
using Prism.Services; using Prism.Services;
using Borepin.Service.BFFH.Exceptions; using Borepin.Service;
using Borepin.Base.Exceptions;
using Capnp.Rpc;
using System;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -20,7 +21,7 @@ namespace Borepin.PageModel
#endregion #endregion
#region Contructors #region Contructors
public MachinePageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bffhService) : base(navigationService, pageDialogService, bffhService) public MachinePageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
UseMachineCommand = new DelegateCommand(UseMachineCommandExecute); UseMachineCommand = new DelegateCommand(UseMachineCommandExecute);
GiveBackMachineCommand = new DelegateCommand(GiveBackMachineCommandExecute); GiveBackMachineCommand = new DelegateCommand(GiveBackMachineCommandExecute);
@ -29,34 +30,25 @@ namespace Borepin.PageModel
#endregion #endregion
#region Data #region Data
public override async Task LoadData() public override Task LoadInstance(object instance)
{ {
IsBusy = true; if(instance is string)
if (!await CheckConnection().ConfigureAwait(false))
{ {
IsConnected = false; _ID = instance as string;
}
IsBusy = false; else
return; {
throw new InstanceIncorrectException();
} }
MachineSystem machineSystem; return Task.CompletedTask;
try }
{
machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
}
catch(ReconnectingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Lost connection to server.", "Ok").ConfigureAwait(false);
return;
}
_Machine = (await machineSystem.Info.GetMachine(_ID).ConfigureAwait(false)).Just; public override async Task LoadAPIData()
{
_Machine = (await _API.Session.MachineSystem.Info.GetMachine(_ID).ConfigureAwait(false)).Just;
MachineItem = new MachineVisualize(_Machine); MachineItem = new MachineVisualize(_Machine);
MachineItem.LoadData(); MachineItem.LoadData();
IsBusy = false;
} }
#endregion #endregion
@ -81,19 +73,22 @@ namespace Borepin.PageModel
public async void UseMachineCommandExecute() public async void UseMachineCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
if(_API.IsConnected)
{ {
IsConnected = false; try
{
Machine.IUseInterface useInterface = _Machine.Use;
IsBusy = false; await useInterface.Use().ConfigureAwait(false);
return; await LoadAPIData().ConfigureAwait(false);
}
catch (RpcException exception) when (string.Equals(exception.Message, "RPC connection is broken. Task would never return.", StringComparison.Ordinal))
{
Log.Debug("RPC Connection Loss");
}
} }
Machine.IUseInterface useInterface = _Machine.Use;
await useInterface.Use().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
IsBusy = false; IsBusy = false;
} }
@ -107,19 +102,22 @@ namespace Borepin.PageModel
public async void GiveBackMachineCommandExecute() public async void GiveBackMachineCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
if (_API.IsConnected)
{ {
IsConnected = false; try
{
Machine.IInUseInterface inUseInterface = _Machine.Inuse;
IsBusy = false; await inUseInterface.GiveBack().ConfigureAwait(false);
return; await LoadAPIData().ConfigureAwait(false);
}
catch(RpcException exception) when(string.Equals(exception.Message, "RPC connection is broken. Task would never return.", StringComparison.Ordinal))
{
Log.Debug("RPC Connection Loss");
}
} }
Machine.IInUseInterface inUseInterface = _Machine.Inuse;
await inUseInterface.GiveBack().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
IsBusy = false; IsBusy = false;
} }
@ -133,35 +131,18 @@ namespace Borepin.PageModel
public async void ForceFreeMachineCommandExecute() public async void ForceFreeMachineCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
if (_API.IsConnected)
{ {
IsConnected = false;
IsBusy = false; Machine.IManageInterface manageInterface = _Machine.Manage;
return;
await manageInterface.ForceFree().ConfigureAwait(false);
await LoadAPIData().ConfigureAwait(false);
} }
Machine.IManageInterface manageInterface = _Machine.Manage;
await manageInterface.ForceFree().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
IsBusy = false; IsBusy = false;
} }
#endregion #endregion
#region INavigationService
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
_ID = parameters["id"] as string;
await LoadData().ConfigureAwait(false);
}
#endregion
} }
} }

View File

@ -1,33 +1,37 @@
using System; using System.Threading.Tasks;
using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Borepin.Base; using Borepin.Base;
using Borepin.Service;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using FabAccessAPI.Schema;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services;
using Xamarin.Forms; using Xamarin.Forms;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class MainPageModel : PageModelBase public class MainPageModel : ConnectionModelBase
{ {
#region Private Members #region Private Members
private readonly IVersioningService _VersioningService; private readonly IVersioningService _VersioningService;
#endregion #endregion
#region Constructors #region Constructors
public MainPageModel(INavigationService navigationService, IVersioningService versioningService) : base(navigationService) public MainPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, IVersioningService versioningService) : base(navigationService, pageDialogService, apiService)
{ {
_VersioningService = versioningService; _VersioningService = versioningService;
CurrentVersion = _VersioningService.CurrentVersion;
CurrentBuild = _VersioningService.CurrentBuild;
NavigateCommand = new Command<string>(NavigateCommandExecute); NavigateCommand = new Command<string>(NavigateCommandExecute);
} }
#endregion #endregion
#region LoadData #region LoadData
public override Task LoadData() public override Task LoadAPIData()
{ {
CurrentVersion = _VersioningService.CurrentVersion; //UserSystem.ManageInterface_Proxy manageInterface = (UserSystem.ManageInterface_Proxy)_API.Session.UserSystem.Manage;
CurrentBuild = _VersioningService.CurrentBuild; //CanManageUsers = !manageInterface.IsNull;
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -47,6 +51,13 @@ namespace Borepin.PageModel
get => _CurrentBuild; get => _CurrentBuild;
set => SetProperty(ref _CurrentBuild, value); set => SetProperty(ref _CurrentBuild, value);
} }
private bool _CanManageUsers;
public bool CanManageUsers
{
get => _CanManageUsers;
set => SetProperty(ref _CanManageUsers, value);
}
#endregion #endregion
#region Commands #region Commands
@ -58,19 +69,11 @@ namespace Borepin.PageModel
} }
public async void NavigateCommandExecute(string view) public async void NavigateCommandExecute(string view)
{ {
await _NavigationService.NavigateAsync($"NavigationPage/{ view }").ConfigureAwait(false); INavigationResult result = await _NavigationService.NavigateAsync($"NavigationPage/{ view }").ConfigureAwait(false);
} if(result.Exception != null)
#endregion {
Log.Fatal(result.Exception, "Navigating failed");
#region INavigationAware }
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
await LoadData().ConfigureAwait(false);
} }
#endregion #endregion
} }

View File

@ -1,7 +1,7 @@
using Borepin.Base; using Borepin.Base;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using System; using Prism.Services;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms; using Xamarin.Forms;
@ -16,9 +16,9 @@ namespace Borepin.PageModel
#endregion #endregion
#region Contructors #region Contructors
public ScanPageModel(INavigationService navigationService) : base(navigationService) public ScanPageModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{ {
AbortCommand = new DelegateCommand(async () => await AbortCommandExecute().ConfigureAwait(true)); CancelCommand = new DelegateCommand(async () => await CancelCommandExecute().ConfigureAwait(true));
ScannedCommand = new DelegateCommand(ScannedCommandExecute); ScannedCommand = new DelegateCommand(ScannedCommandExecute);
IsVisible = true; IsVisible = true;
@ -27,9 +27,15 @@ namespace Borepin.PageModel
#endregion #endregion
#region Data #region Data
public override async Task LoadData() public override Task LoadInstance(object instance)
{ {
await Task.CompletedTask.ConfigureAwait(false); _Instance = instance;
return Task.CompletedTask;
}
public override Task<object> CreateInstance()
{
return Task.FromResult(_Instance);
} }
#endregion #endregion
@ -73,7 +79,6 @@ namespace Borepin.PageModel
{ {
{ "result", "scanned" }, { "result", "scanned" },
{ "value", ScanResult.Text }, { "value", ScanResult.Text },
{ "instance", _Instance },
}; };
Device.BeginInvokeOnMainThread(async () => Device.BeginInvokeOnMainThread(async () =>
@ -82,36 +87,23 @@ namespace Borepin.PageModel
}); });
} }
private ICommand _AbortCommand; private ICommand _CancelCommand;
public ICommand AbortCommand public ICommand CancelCommand
{ {
get => _AbortCommand; get => _CancelCommand;
set => SetProperty(ref _AbortCommand, value); set => SetProperty(ref _CancelCommand, value);
} }
public async Task AbortCommandExecute() public async Task CancelCommandExecute()
{ {
IsScanning = false; IsScanning = false;
IsVisible = false; IsVisible = false;
INavigationParameters parameters = new NavigationParameters() INavigationParameters parameters = new NavigationParameters()
{ {
{ "result", "abort" }, { "result", "canceled" },
{ "instance", _Instance },
}; };
await _NavigationService.GoBackAsync(parameters).ConfigureAwait(false); await _NavigationService.GoBackAsync(parameters).ConfigureAwait(false);
} }
#endregion #endregion
#region INavigationService
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
_Instance = parameters.GetValue<object>("instance");
}
#endregion
} }
} }

View File

@ -1,6 +1,5 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
@ -17,9 +16,9 @@ namespace Borepin.PageModel
class ScanURNPageModel : ConnectionModelBase class ScanURNPageModel : ConnectionModelBase
{ {
#region Contructors #region Contructors
public ScanURNPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bffhService) : base(navigationService, pageDialogService, bffhService) public ScanURNPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
AbortCommand = new DelegateCommand(async () => await AbortCommandExecute().ConfigureAwait(true)); CancelCommand = new DelegateCommand(async () => await CancelCommandExecute().ConfigureAwait(true));
ScannedCommand = new DelegateCommand(async () => await ScannedCommandExecuteAsync().ConfigureAwait(false)); ScannedCommand = new DelegateCommand(async () => await ScannedCommandExecuteAsync().ConfigureAwait(false));
IsVisible = true; IsVisible = true;
@ -27,13 +26,6 @@ namespace Borepin.PageModel
} }
#endregion #endregion
#region Data
public override async Task LoadData()
{
await Task.CompletedTask.ConfigureAwait(false);
}
#endregion
#region Fields #region Fields
public MobileBarcodeScanningOptions ScanOptions public MobileBarcodeScanningOptions ScanOptions
{ {
@ -98,28 +90,15 @@ namespace Borepin.PageModel
return; return;
} }
// END HACK // END HACK
string id = null;
try
{
id = await QRToID(ScanResult.Text).ConfigureAwait(false);
}
catch(ReconnectingFailedException)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Please reconnect to the server.", "OK").ConfigureAwait(false);
IsScanning = true;
});
return; string id = await QRToID(ScanResult.Text).ConfigureAwait(false);
}
if (id != null) if (id != null)
{ {
NavigationParameters parameters = new NavigationParameters NavigationParameters parameters = new NavigationParameters
{ {
{ "id", id }, { "instance", id },
}; };
Device.BeginInvokeOnMainThread(async () => Device.BeginInvokeOnMainThread(async () =>
{ {
@ -141,33 +120,30 @@ namespace Borepin.PageModel
public async Task<string> QRToID(string value) public async Task<string> QRToID(string value)
{ {
if (!_BFFHService.IsConnected) if (_API.IsConnected)
{ {
await _BFFHService.Reconnect().ConfigureAwait(false); Optional<Machine> optional = await _API.Session.MachineSystem.Info.GetMachineURN(value).ConfigureAwait(false);
IsConnected = false; if (optional.Just == null)
return null; {
return null;
}
return optional.Just.Id;
} }
else
MachineSystem machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
Optional<Machine> optional = await machineSystem.Info.GetMachineURN(value).ConfigureAwait(false);
if (optional.Just == null)
{ {
return null; return null;
} }
return optional.Just.Id;
} }
private ICommand _AbortCommand; private ICommand _CancelCommand;
public ICommand AbortCommand public ICommand CancelCommand
{ {
get => _AbortCommand; get => _CancelCommand;
set => SetProperty(ref _AbortCommand, value); set => SetProperty(ref _CancelCommand, value);
} }
public async Task AbortCommandExecute() public async Task CancelCommandExecute()
{ {
IsScanning = false; IsScanning = false;
IsVisible = false; IsVisible = false;
@ -175,17 +151,5 @@ namespace Borepin.PageModel
await _NavigationService.GoBackAsync().ConfigureAwait(false); await _NavigationService.GoBackAsync().ConfigureAwait(false);
} }
#endregion #endregion
#region INavigationService
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
} }
} }

View File

@ -1,41 +1,45 @@
using Borepin.ViewModel; using Borepin.ViewModel;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq;
using Borepin.Model;
using System.Windows.Input; using System.Windows.Input;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Borepin.Service.BFFH;
using Borepin.Base; using Borepin.Base;
using Borepin.Service.Storage;
using FabAccessAPI;
using Borepin.Service;
using Prism.Services;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class ServerListPageModel : PageModelBase public class ServerListPageModel : PageModelBase
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private readonly ILoginStorageService _LoginStorageService;
private readonly IAPI _API;
#endregion #endregion
#region Constructors #region Constructors
public ServerListPageModel(INavigationService navigationService, IBFFHService bffhService) : base(navigationService) public ServerListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, ILoginStorageService loginStorageService, IAPIService apiService) : base(navigationService, pageDialogService)
{ {
_BFFHService = bffhService; _LoginStorageService = loginStorageService;
_API = apiService.GetAPI();
AddInstancesCommand = new DelegateCommand(AddInstancesCommandExecute); AddInstancesCommand = new DelegateCommand(AddInstancesCommandExecute);
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute); SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute);
} }
#endregion #endregion
#region Data #region LoadData
public override async Task LoadData() public override async Task LoadInstance(object instance)
{ {
IList<Connection> list = await _BFFHService.GetConnections().ConfigureAwait(false); IList<ConnectionData> list = await _LoginStorageService.GetList().ConfigureAwait(false);
if (_BFFHService.IsConnected) if (_API.IsConnected)
{ {
ActiveConnection = new ServerListItemViewModel(_BFFHService.CurrentConnection); ActiveConnection = new ServerListItemViewModel(_NavigationService, _PageDialogService);
await ActiveConnection.LoadInstance(_API.ConnectionData).ConfigureAwait(false);
list.Remove(_BFFHService.CurrentConnection); list.Remove(_API.ConnectionData);
HasActiveConnection = true; HasActiveConnection = true;
} }
@ -44,7 +48,15 @@ namespace Borepin.PageModel
HasActiveConnection = false; HasActiveConnection = false;
} }
ServerListItemViewModel_List = list.Select(x => new ServerListItemViewModel(x)).ToList(); List<ServerListItemViewModel> serverListItemViewModel_List = new List<ServerListItemViewModel>();
foreach (ConnectionData connectionData in list)
{
ServerListItemViewModel serverListItemViewModel = new ServerListItemViewModel(_NavigationService, _PageDialogService);
await serverListItemViewModel.LoadInstance(connectionData).ConfigureAwait(false);
serverListItemViewModel_List.Add(serverListItemViewModel);
}
ServerListItemViewModel_List = serverListItemViewModel_List;
IsBusy = false; IsBusy = false;
} }
@ -103,17 +115,5 @@ namespace Borepin.PageModel
await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false); await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false);
} }
#endregion #endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
await LoadData().ConfigureAwait(false);
}
#endregion
} }
} }

View File

@ -1,7 +1,9 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Base.Exceptions;
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions; using Borepin.Service.Storage;
using FabAccessAPI;
using FabAccessAPI.Exceptions;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
@ -10,56 +12,77 @@ using System;
using System.Globalization; using System.Globalization;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class ServerPageModel : PageModelBase public class ServerPageModel : ConnectionModelBase
{ {
#region Private Fields #region Private Fields
private readonly IDialogService _DialogService; private readonly IDialogService _DialogService;
private readonly IBFFHService _BFFHService; private readonly ILoginStorageService _LoginStorageService;
private readonly IPageDialogService _PageDialogService; private bool IsDialog = false;
#endregion #endregion
#region Constructors #region Constructors
public ServerPageModel(INavigationService navigationService, IDialogService dialogService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService) public ServerPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, IDialogService dialogService, ILoginStorageService loginStorageService) : base(navigationService, pageDialogService, apiService)
{ {
_DialogService = dialogService; _DialogService = dialogService;
_LoginStorageService = loginStorageService;
_BFFHService = bffhService;
_PageDialogService = pageDialogService;
ConnectCommand = new DelegateCommand(async () => await ConnectCommandExecute().ConfigureAwait(false)); ConnectCommand = new DelegateCommand(async () => await ConnectCommandExecute().ConfigureAwait(false));
DisconnectCommand = new DelegateCommand(async () => await DisonnectCommandExecute().ConfigureAwait(false)); DisconnectCommand = new DelegateCommand(async () => await DisonnectCommandExecute().ConfigureAwait(false));
DeleteCommand = new DelegateCommand(DeleteCommandExecute); DeleteCommand = new DelegateCommand(DeleteCommandExecute);
SetDefaultCommand = new DelegateCommand(async () => await SetDefaultCommandExecute().ConfigureAwait(false));
} }
#endregion #endregion
#region Data #region Data
public override Task LoadData() public override async Task LoadInstance(object instance)
{ {
if (_BFFHService.CurrentConnection != null && Connection_Item != null) if(instance != null)
{ {
InstanceIsActiveConnection = Connection_Item.Equals(_BFFHService.CurrentConnection); if(instance is ConnectionData)
} {
else Connection_Item = instance as ConnectionData;
{ }
InstanceIsActiveConnection = false; else
} {
throw new InstanceIncorrectException();
}
if(_Connection_Item != null && _Connection_Item.Address != null) if(_API.ConnectionData != null && Connection_Item != null)
{
InstanceIsActiveConnection = Connection_Item.Equals(_API.ConnectionData);
}
else
{
InstanceIsActiveConnection = false;
}
if(_Connection_Item != null && _Connection_Item.Host != null)
{
DisplayAddress = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", _Connection_Item.Host.Host, _Connection_Item.Host.Port);
}
ConnectionData connectionData_Default = await _LoginStorageService.GetDefault().ConfigureAwait(false);
if(connectionData_Default != null && connectionData_Default.Equals(_Connection_Item))
{
InstanceIsDefaultConnection = true;
}
}
if(instance == null && Connection_Item == null && IsDialog == false)
{ {
DisplayAddress = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", _Connection_Item.Address.Host, _Connection_Item.Address.Port); throw new InstanceIncorrectException();
} }
IsBusy = false; IsBusy = false;
return Task.CompletedTask;
} }
#endregion #endregion
#region Fields #region Fields
private Connection _Connection_Item; private ConnectionData _Connection_Item;
public Connection Connection_Item public ConnectionData Connection_Item
{ {
get => _Connection_Item; get => _Connection_Item;
set => SetProperty(ref _Connection_Item, value); set => SetProperty(ref _Connection_Item, value);
@ -78,6 +101,13 @@ namespace Borepin.PageModel
get => _InstanceIsActiveConnection; get => _InstanceIsActiveConnection;
set => SetProperty(ref _InstanceIsActiveConnection, value); set => SetProperty(ref _InstanceIsActiveConnection, value);
} }
private bool _InstanceIsDefaultConnection;
public bool InstanceIsDefaultConnection
{
get => _InstanceIsDefaultConnection;
set => SetProperty(ref _InstanceIsDefaultConnection, value);
}
#endregion #endregion
#region Commands #region Commands
@ -91,39 +121,59 @@ namespace Borepin.PageModel
{ {
IsBusy = true; IsBusy = true;
if(_BFFHService.IsConnected) if(_API.IsConnected)
{ {
await _BFFHService.Disconnect().ConfigureAwait(true); await _API.Disconnect().ConfigureAwait(true);
_API.UnbindAllEvents();
} }
try try
{ {
await _BFFHService.Connect(Connection_Item).ConfigureAwait(true); await _API.Connect(Connection_Item).ConfigureAwait(false);
} }
catch(ConnectingFailedException) catch(ConnectingFailedException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
IsBusy = false; await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
});
return; return;
} }
catch(AuthenticatingFailedException) catch(AuthenticationFailedException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false);
IsBusy = false; IsBusy = false;
});
return; return;
} }
catch(MissingCredentialsException)
await _LoginStorageService.UpdateTimestamp(_Connection_Item).ConfigureAwait(false);
Device.BeginInvokeOnMainThread(async () =>
{ {
await _PageDialogService.DisplayAlertAsync("Secure Storage failed", "Unable to load connections from secure storage.\n Please recreate the connection.", "Ok").ConfigureAwait(false); INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
private ICommand _SetDefaultCommand;
public ICommand SetDefaultCommand
{
get => _SetDefaultCommand;
set => SetProperty(ref _SetDefaultCommand, value);
}
public async Task SetDefaultCommandExecute()
{
await _LoginStorageService.SetDefault(Connection_Item).ConfigureAwait(false);
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false); await LoadInstance(Connection_Item).ConfigureAwait(false);
IsBusy = false;
return;
}
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
} }
private ICommand _DisconnectCommand; private ICommand _DisconnectCommand;
@ -134,9 +184,10 @@ namespace Borepin.PageModel
} }
public async Task DisonnectCommandExecute() public async Task DisonnectCommandExecute()
{ {
await _BFFHService.Disconnect().ConfigureAwait(false); _API.UnbindAllEvents();
await _API.Disconnect().ConfigureAwait(false);
await LoadData().ConfigureAwait(false); await LoadInstance(Connection_Item).ConfigureAwait(false);
} }
private ICommand _DeleteCommand; private ICommand _DeleteCommand;
@ -155,6 +206,7 @@ namespace Borepin.PageModel
{ "instance", Connection_Item }, { "instance", Connection_Item },
}; };
IsDialog = true;
_DialogService.ShowDialog("ConfirmDialog", parameters, DeleteCommandExecute_Dialog); _DialogService.ShowDialog("ConfirmDialog", parameters, DeleteCommandExecute_Dialog);
} }
@ -162,28 +214,18 @@ namespace Borepin.PageModel
{ {
if(string.Equals(result.Parameters.GetValue<string>("result"), "confirm", StringComparison.Ordinal)) if(string.Equals(result.Parameters.GetValue<string>("result"), "confirm", StringComparison.Ordinal))
{ {
Connection connection = result.Parameters.GetValue<Connection>("instance"); await _API.Disconnect().ConfigureAwait(false);
_API.UnbindAllEvents();
await _LoginStorageService.Remove(result.Parameters.GetValue<ConnectionData>("instance")).ConfigureAwait(false);
await _BFFHService.RemoveConnection(connection).ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false); INavigationResult result_nav = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
} if (result_nav.Exception != null)
} {
#endregion Log.Fatal(result.Exception, "Navigating failed");
}
#region INavigationAware });
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
if(Connection_Item == null)
{
Connection_Item = parameters["instance"] as Connection;
await LoadData().ConfigureAwait(false);
} }
} }
#endregion #endregion

View File

@ -1,28 +1,21 @@
using Borepin.Base; using Borepin.Base;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using System; using Prism.Services;
using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.SetUpProcess namespace Borepin.PageModel.SetUpProcess
{ {
public class WelcomePageModel : PageModelBase public class WelcomePageModel : PageModelBase
{ {
#region Constructors #region Constructors
public WelcomePageModel(INavigationService navigationService) : base(navigationService) public WelcomePageModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{ {
NextCommand = new DelegateCommand<object>(NextCommandCommandExecute); NextCommand = new DelegateCommand<object>(NextCommandCommandExecute);
} }
#endregion #endregion
#region Data
public override Task LoadData()
{
return Task.CompletedTask;
}
#endregion
#region Commands #region Commands
private ICommand _NextCommand; private ICommand _NextCommand;
public ICommand NextCommand public ICommand NextCommand
@ -30,20 +23,16 @@ namespace Borepin.PageModel.SetUpProcess
get => _NextCommand; get => _NextCommand;
set => SetProperty(ref _NextCommand, value); set => SetProperty(ref _NextCommand, value);
} }
public async void NextCommandCommandExecute(object obj) public void NextCommandCommandExecute(object obj)
{
await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false);
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{ {
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
#endregion #endregion

View File

@ -1,51 +1,92 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Service;
using Borepin.Service.BFFH; using Borepin.Service.Storage;
using FabAccessAPI;
using Prism.AppModel; using Prism.AppModel;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using Xamarin.Forms;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class StartPageModel : PageModelBase, IPageLifecycleAware, IInitialize public class StartPageModel : ConnectionModelBase, IPageLifecycleAware
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private readonly ILoginStorageService _LoginStorageService;
#endregion #endregion
#region Constructors #region Constructors
public StartPageModel(INavigationService navigationService, IBFFHService bffhService) : base(navigationService) public StartPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, ILoginStorageService loginStorageService) : base(navigationService, pageDialogService, apiService)
{ {
_BFFHService = bffhService; _LoginStorageService = loginStorageService;
} }
#endregion #endregion
#region LoadData #region Fields
public override Task LoadData() private bool _IsConnecting;
public bool IsConnecting
{ {
return Task.CompletedTask; get => _IsConnecting;
} set => SetProperty(ref _IsConnecting, value);
#endregion
#region IInitialize
public void Initialize(INavigationParameters parameters)
{
} }
#endregion #endregion
#region IPageLifecycleAware #region IPageLifecycleAware
public async void OnAppearing() public async void OnAppearing()
{ {
IList<Connection> connection_list = await _BFFHService.GetConnections().ConfigureAwait(false); IList<ConnectionData> connectionData_List = await _LoginStorageService.GetList().ConfigureAwait(false);
if (connection_list.Count == 0) ConnectionData connectionData_Default = await _LoginStorageService.GetDefault().ConfigureAwait(false);
if (connectionData_List.Count == 0)
{ {
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/SetUpProcess_WelcomePage").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/SetUpProcess_WelcomePage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
else if(connectionData_Default != null)
{
IsBusy = false;
IsConnecting = true;
try
{
await _API.Connect(connectionData_Default).ConfigureAwait(false);
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
catch
{
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
} }
else else
{ {
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false); Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
} }
@ -54,17 +95,5 @@ namespace Borepin.PageModel
} }
#endregion #endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
} }
} }

View File

@ -0,0 +1,78 @@
using Borepin.ViewModel;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;
using Prism.Commands;
using Prism.Navigation;
using Borepin.Base;
using FabAccessAPI.Schema;
using Prism.Services;
using System;
using NaturalSort.Extension;
using System.Linq;
using Borepin.Service;
namespace Borepin.PageModel
{
public class UserListPageModel : ConnectionModelBase
{
#region Constructors
public UserListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{
RefreshCommand = new DelegateCommand(async ()=> await RefreshCommandExecute().ConfigureAwait(true));
}
#endregion
#region Data
public override async Task LoadAPIData()
{
IReadOnlyList<User> user_list = await _API.Session.UserSystem.Manage.GetUserList().ConfigureAwait(false);
List<UserListItemViewModel> viewmodel_list= new List<UserListItemViewModel>();
foreach (User user in user_list)
{
UserListItemViewModel new_viewmodel = new UserListItemViewModel(_NavigationService, _PageDialogService);
await new_viewmodel.LoadInstance(user).ConfigureAwait(false);
viewmodel_list.Add(new_viewmodel);
}
user_list.OrderBy(x => x.Username, StringComparison.OrdinalIgnoreCase.WithNaturalSort());
UserListItemViewModel_List = viewmodel_list;
}
#endregion
#region Fields
private IList<UserListItemViewModel> _UserListItemViewModel_List;
public IList<UserListItemViewModel> UserListItemViewModel_List
{
get => _UserListItemViewModel_List;
set => SetProperty(ref _UserListItemViewModel_List, value);
}
private bool _IsRefreshing;
public bool IsRefreshing
{
get => _IsRefreshing;
set => SetProperty(ref _IsRefreshing, value);
}
#endregion
#region Commands
private ICommand _RefreshCommand;
public ICommand RefreshCommand
{
get => _RefreshCommand;
set => SetProperty(ref _RefreshCommand, value);
}
public async Task RefreshCommandExecute()
{
if(_API.IsConnected)
{
await LoadAPIData().ConfigureAwait(true);
}
IsRefreshing = false;
}
#endregion
}
}

View File

@ -0,0 +1,66 @@
using Borepin.Base;
using Prism.Commands;
using Prism.Navigation;
using System.Threading.Tasks;
using System.Windows.Input;
using FabAccessAPI.Schema;
using Borepin.Model;
using Prism.Services;
using Borepin.Service;
using Borepin.Base.Exceptions;
using Capnp.Rpc;
using System;
namespace Borepin.PageModel
{
public class UserPageModel : ConnectionModelBase
{
#region Private Fields
private string _ID;
private User _User;
#endregion
#region Contructors
public UserPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{
}
#endregion
#region Data
public override Task LoadInstance(object instance)
{
if(instance is string)
{
_ID = instance as string;
}
else
{
throw new InstanceIncorrectException();
}
return Task.CompletedTask;
}
public override async Task LoadAPIData()
{
_User = (await _API.Session.UserSystem.Search.GetUserByName(_ID).ConfigureAwait(false)).Just;
UserItem = new UserVisualize(_User);
UserItem.LoadData();
}
#endregion
#region Fields
private UserVisualize _UserItem;
public UserVisualize UserItem
{
get => _UserItem;
set => SetProperty(ref _UserItem, value);
}
#endregion
#region Commands
#endregion
}
}

View File

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Borepin.Properties {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Borepin.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -10,35 +10,48 @@
namespace Borepin.Resources.Text { namespace Borepin.Resources.Text {
using System; using System;
using System.Reflection;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] /// <summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()] /// A strongly-typed resource class, for looking up localized strings, etc.
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()] /// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TextResource { internal class TextResource {
private static System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture; private static global::System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal TextResource() { internal TextResource() {
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] /// <summary>
internal static System.Resources.ResourceManager ResourceManager { /// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.Equals(null, resourceMan)) { if (object.ReferenceEquals(resourceMan, null)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Borepin.Resources.Text.TextResource", typeof(TextResource).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Borepin.Resources.Text.TextResource", typeof(TextResource).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] /// <summary>
internal static System.Globalization.CultureInfo Culture { /// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@ -47,33 +60,381 @@ namespace Borepin.Resources.Text {
} }
} }
internal static string SetUp_ScanPage_Button { /// <summary>
/// Looks up a localized string similar to Login.
/// </summary>
internal static string AddServerProcess_AuthPlainPage_Login {
get { get {
return ResourceManager.GetString("SetUp_ScanPage_Button", resourceCulture); return ResourceManager.GetString("AddServerProcess_AuthPlainPage_Login", resourceCulture);
} }
} }
internal static string SetUp_ScanPage_Text { /// <summary>
/// Looks up a localized string similar to Login with Card.
/// </summary>
internal static string AddServerProcess_ChooseAuthTypePage_LoginCard {
get { get {
return ResourceManager.GetString("SetUp_ScanPage_Text", resourceCulture); return ResourceManager.GetString("AddServerProcess_ChooseAuthTypePage_LoginCard", resourceCulture);
} }
} }
internal static string SetUp_WelcomePage_Button { /// <summary>
/// Looks up a localized string similar to Login with Password.
/// </summary>
internal static string AddServerProcess_ChooseAuthTypePage_LoginPassword {
get { get {
return ResourceManager.GetString("SetUp_WelcomePage_Button", resourceCulture); return ResourceManager.GetString("AddServerProcess_ChooseAuthTypePage_LoginPassword", resourceCulture);
} }
} }
internal static string SetUp_WelcomePage_Text { /// <summary>
/// Looks up a localized string similar to Register.
/// </summary>
internal static string AddServerProcess_ChooseAuthTypePage_Register {
get { get {
return ResourceManager.GetString("SetUp_WelcomePage_Text", resourceCulture); return ResourceManager.GetString("AddServerProcess_ChooseAuthTypePage_Register", resourceCulture);
} }
} }
internal static string SetUp_WelcomePage_Title { /// <summary>
/// Looks up a localized string similar to Sign In:.
/// </summary>
internal static string AddServerProcess_ChooseAuthTypePage_SignIn {
get { get {
return ResourceManager.GetString("SetUp_WelcomePage_Title", resourceCulture); return ResourceManager.GetString("AddServerProcess_ChooseAuthTypePage_SignIn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sign Up:.
/// </summary>
internal static string AddServerProcess_ChooseAuthTypePage_SignUp {
get {
return ResourceManager.GetString("AddServerProcess_ChooseAuthTypePage_SignUp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connect to Server.
/// </summary>
internal static string AddServerProcess_SelectServerPage_Connect {
get {
return ResourceManager.GetString("AddServerProcess_SelectServerPage_Connect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PLACEHOLDER.
/// </summary>
internal static string AddServerProcess_SelectServerPage_Info {
get {
return ResourceManager.GetString("AddServerProcess_SelectServerPage_Info", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cancel.
/// </summary>
internal static string CANCEL {
get {
return ResourceManager.GetString("CANCEL", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Delete.
/// </summary>
internal static string DELETE {
get {
return ResourceManager.GetString("DELETE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Host.
/// </summary>
internal static string HOST {
get {
return ResourceManager.GetString("HOST", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PLACEHOLDER.
/// </summary>
internal static string MachinePage_CanNotUseByPermission {
get {
return ResourceManager.GetString("MachinePage_CanNotUseByPermission", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Current User:.
/// </summary>
internal static string MachinePage_CurrentUser {
get {
return ResourceManager.GetString("MachinePage_CurrentUser", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Force Free.
/// </summary>
internal static string MachinePage_ForceFree {
get {
return ResourceManager.GetString("MachinePage_ForceFree", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to GiveBack.
/// </summary>
internal static string MachinePage_GiveBack {
get {
return ResourceManager.GetString("MachinePage_GiveBack", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Last User:.
/// </summary>
internal static string MachinePage_LastUser {
get {
return ResourceManager.GetString("MachinePage_LastUser", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Manage Machine:.
/// </summary>
internal static string MachinePage_ManageMachine {
get {
return ResourceManager.GetString("MachinePage_ManageMachine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use.
/// </summary>
internal static string MachinePage_Use {
get {
return ResourceManager.GetString("MachinePage_Use", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Build.
/// </summary>
internal static string MainPage_Build {
get {
return ResourceManager.GetString("MainPage_Build", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Machines.
/// </summary>
internal static string MainPage_Machines {
get {
return ResourceManager.GetString("MainPage_Machines", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Servers.
/// </summary>
internal static string MainPage_Servers {
get {
return ResourceManager.GetString("MainPage_Servers", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Users.
/// </summary>
internal static string MainPage_Users {
get {
return ResourceManager.GetString("MainPage_Users", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Version.
/// </summary>
internal static string MainPage_Version {
get {
return ResourceManager.GetString("MainPage_Version", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to or.
/// </summary>
internal static string OR {
get {
return ResourceManager.GetString("OR", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password.
/// </summary>
internal static string PASSWORD {
get {
return ResourceManager.GetString("PASSWORD", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Please connect to Server.
/// </summary>
internal static string PLEASECONNECTTOSERVER {
get {
return ResourceManager.GetString("PLEASECONNECTTOSERVER", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Scan QR-Code.
/// </summary>
internal static string SCANQR {
get {
return ResourceManager.GetString("SCANQR", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Active Connection.
/// </summary>
internal static string ServerListPage_ActiveConnection {
get {
return ResourceManager.GetString("ServerListPage_ActiveConnection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connect to new Server.
/// </summary>
internal static string ServerListPage_ConnectToNewServer {
get {
return ResourceManager.GetString("ServerListPage_ConnectToNewServer", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Last Connections.
/// </summary>
internal static string ServerListPage_LastConnection {
get {
return ResourceManager.GetString("ServerListPage_LastConnection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connect.
/// </summary>
internal static string ServerPage_Connect {
get {
return ResourceManager.GetString("ServerPage_Connect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Disconnect.
/// </summary>
internal static string ServerPage_Disconnect {
get {
return ResourceManager.GetString("ServerPage_Disconnect", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Is Default Connection.
/// </summary>
internal static string ServerPage_IsDefault {
get {
return ResourceManager.GetString("ServerPage_IsDefault", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Set as Default Connection.
/// </summary>
internal static string ServerPage_SetDefault {
get {
return ResourceManager.GetString("ServerPage_SetDefault", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connection failed.
/// </summary>
internal static string ServerPageModel_ConnectionFailed {
get {
return ResourceManager.GetString("ServerPageModel_ConnectionFailed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Login to your Space.
/// </summary>
internal static string SetUpProcess_ScanPage_Button {
get {
return ResourceManager.GetString("SetUpProcess_ScanPage_Button", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Begin working.
/// </summary>
internal static string SetUpProcess_WelcomePage_Button {
get {
return ResourceManager.GetString("SetUpProcess_WelcomePage_Button", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Automate your Space with FabAccess.
/// </summary>
internal static string SetUpProcess_WelcomePage_Text {
get {
return ResourceManager.GetString("SetUpProcess_WelcomePage_Text", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Welcome.
/// </summary>
internal static string SetUpProcess_WelcomePage_Title {
get {
return ResourceManager.GetString("SetUpProcess_WelcomePage_Title", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connecting to Server.
/// </summary>
internal static string StartPage_Connecting {
get {
return ResourceManager.GetString("StartPage_Connecting", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Starting App.
/// </summary>
internal static string StartPage_Starting {
get {
return ResourceManager.GetString("StartPage_Starting", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Username.
/// </summary>
internal static string USERNAME {
get {
return ResourceManager.GetString("USERNAME", resourceCulture);
} }
} }
} }

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -117,19 +117,132 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="SetUp_ScanPage_Button" xml:space="preserve"> <data name="AddServerProcess_AuthPlainPage_Login" xml:space="preserve">
<value>Login</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_LoginCard" xml:space="preserve">
<value>Login with Card</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_LoginPassword" xml:space="preserve">
<value>Login with Password</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_Register" xml:space="preserve">
<value>Register</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_SignIn" xml:space="preserve">
<value>Sign In:</value>
</data>
<data name="AddServerProcess_ChooseAuthTypePage_SignUp" xml:space="preserve">
<value>Sign Up:</value>
</data>
<data name="AddServerProcess_SelectServerPage_Connect" xml:space="preserve">
<value>Connect to Server</value>
</data>
<data name="AddServerProcess_SelectServerPage_Info" xml:space="preserve">
<value>PLACEHOLDER</value>
<comment>Server Struktur erklären, auf QR-Code hinweisen, ansonsten im Space fragen</comment>
</data>
<data name="CANCEL" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="DELETE" xml:space="preserve">
<value>Delete</value>
</data>
<data name="HOST" xml:space="preserve">
<value>Host</value>
</data>
<data name="MachinePage_CanNotUseByPermission" xml:space="preserve">
<value>PLACEHOLDER</value>
<comment>Nutzer darf die Maschine nicht nutzten, dass sollte erklärt werden, also beim Admin nachfragen</comment>
</data>
<data name="MachinePage_CurrentUser" xml:space="preserve">
<value>Current User:</value>
</data>
<data name="MachinePage_ForceFree" xml:space="preserve">
<value>Force Free</value>
</data>
<data name="MachinePage_GiveBack" xml:space="preserve">
<value>GiveBack</value>
</data>
<data name="MachinePage_LastUser" xml:space="preserve">
<value>Last User:</value>
</data>
<data name="MachinePage_ManageMachine" xml:space="preserve">
<value>Manage Machine:</value>
</data>
<data name="MachinePage_Use" xml:space="preserve">
<value>Use</value>
</data>
<data name="MainPage_Build" xml:space="preserve">
<value>Build</value>
</data>
<data name="MainPage_Machines" xml:space="preserve">
<value>Machines</value>
</data>
<data name="MainPage_Servers" xml:space="preserve">
<value>Servers</value>
</data>
<data name="MainPage_Users" xml:space="preserve">
<value>Users</value>
</data>
<data name="MainPage_Version" xml:space="preserve">
<value>Version</value>
</data>
<data name="OR" xml:space="preserve">
<value>or</value>
</data>
<data name="PASSWORD" xml:space="preserve">
<value>Password</value>
</data>
<data name="PLEASECONNECTTOSERVER" xml:space="preserve">
<value>Please connect to Server</value>
</data>
<data name="SCANQR" xml:space="preserve">
<value>Scan QR-Code</value>
</data>
<data name="ServerListPage_ActiveConnection" xml:space="preserve">
<value>Active Connection</value>
</data>
<data name="ServerListPage_ConnectToNewServer" xml:space="preserve">
<value>Connect to new Server</value>
</data>
<data name="ServerListPage_LastConnection" xml:space="preserve">
<value>Last Connections</value>
</data>
<data name="ServerPageModel_ConnectionFailed" xml:space="preserve">
<value>Connection failed</value>
</data>
<data name="ServerPage_Connect" xml:space="preserve">
<value>Connect</value>
</data>
<data name="ServerPage_Disconnect" xml:space="preserve">
<value>Disconnect</value>
</data>
<data name="ServerPage_IsDefault" xml:space="preserve">
<value>Is Default Connection</value>
</data>
<data name="ServerPage_SetDefault" xml:space="preserve">
<value>Set as Default Connection</value>
</data>
<data name="SetUpProcess_ScanPage_Button" xml:space="preserve">
<value>Login to your Space</value> <value>Login to your Space</value>
</data> </data>
<data name="SetUp_ScanPage_Text" xml:space="preserve"> <data name="SetUpProcess_WelcomePage_Button" xml:space="preserve">
<value>Wenn du dieses Logo siehst, dann kannst du es scannen</value>
</data>
<data name="SetUp_WelcomePage_Button" xml:space="preserve">
<value>Begin working</value> <value>Begin working</value>
</data> </data>
<data name="SetUp_WelcomePage_Text" xml:space="preserve"> <data name="SetUpProcess_WelcomePage_Text" xml:space="preserve">
<value>Automate your Space with FabAccess</value> <value>Automate your Space with FabAccess</value>
</data> </data>
<data name="SetUp_WelcomePage_Title" xml:space="preserve"> <data name="SetUpProcess_WelcomePage_Title" xml:space="preserve">
<value>Welcome</value> <value>Welcome</value>
</data> </data>
<data name="StartPage_Connecting" xml:space="preserve">
<value>Connecting to Server</value>
</data>
<data name="StartPage_Starting" xml:space="preserve">
<value>Starting App</value>
</data>
<data name="USERNAME" xml:space="preserve">
<value>Username</value>
</data>
</root> </root>

View File

@ -1,330 +0,0 @@
using System;
using Borepin.Model;
using System.Threading.Tasks;
using System.Collections.Generic;
using FabAccessAPI.Schema;
using Borepin.Service.Storage;
using Borepin.Model.Storage;
using Borepin.Service.BFFH.Exceptions;
using Borepin.Service.Storage.Exceptions;
using Capnp.Rpc;
using FabAccessAPI.Exceptions;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Security.Authentication;
namespace Borepin.Service.BFFH
{
public class BFFHService : IBFFHService
{
#region Private Fields
private readonly ConnectionStorage _ConnectionStorage;
private readonly ConnectionCredentialStorage _ConnectionCredentialStorage;
private FabAccessAPI.Connection _APIConnection;
private Connection_Plain _CurrentConnection;
#endregion
#region Constructors
public BFFHService(IPreferenceStorageService preferenceStorageService, ISecretStorageService secretStorageService)
{
_ConnectionStorage = new ConnectionStorage(preferenceStorageService);
_ConnectionCredentialStorage = new ConnectionCredentialStorage(secretStorageService);
}
#endregion
#region Fields
/// <summary>
/// Current Connection of Service
/// </summary>
public Connection CurrentConnection
{
get
{
return _CurrentConnection;
}
}
/// <summary>
/// Check if Service is connected to a Server
/// </summary>
public bool IsConnected
{
get
{
if (_APIConnection != null && _APIConnection.RpcClient != null)
{
return _APIConnection.RpcClient.State == Capnp.Rpc.ConnectionState.Active;
}
return false;
}
}
#endregion
#region Method
/// <summary>
/// Get all known Connections from Storage
/// </summary>
public async Task<IList<Connection>> GetConnections()
{
return await _ConnectionStorage.GetConnectionList().ConfigureAwait(false);
}
/// <summary>
/// Remove Connection from Storage
/// </summary>
public async Task RemoveConnection(Connection connection)
{
if (IsConnected && connection.Equals(CurrentConnection))
{
await Disconnect().ConfigureAwait(false);
}
try
{
await _ConnectionCredentialStorage.RemoveCredentials(connection).ConfigureAwait(false);
}
catch (KeyNotFoundException)
{
}
try
{
await _ConnectionStorage.RemoveConnection(connection).ConfigureAwait(false);
}
catch (KeyNotFoundException)
{
}
}
/// <summary>
/// Test a if a Server is reachable
/// </summary>
public async Task<bool> TestConnection(Connection connection)
{
try
{
TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
rpcClient.Dispose();
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Connects to Server with Credential from ConnectionCredentialStorage
/// </summary>
/// <exception cref="AllreadyConnectedException"></exception>
/// <exception cref="MissingCredentialsException"></exception>
/// <exception cref="ConnectingFailedException"></exception>
/// <exception cref="AuthenticatingFailedException"></exception>
public async Task Connect(Connection connection)
{
if (IsConnected)
{
throw new AllreadyConnectedException();
}
string password;
try
{
password = await _ConnectionCredentialStorage.GetPassword(connection).ConfigureAwait(false);
}
catch (KeyNotFoundException)
{
await _ConnectionCredentialStorage.RemoveAllCredentials().ConfigureAwait(false);
await _ConnectionStorage.RemoveAllConnections().ConfigureAwait(false);
throw new MissingCredentialsException();
}
try
{
TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
_APIConnection = new FabAccessAPI.Connection(rpcClient);
}
catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
{
throw new ConnectingFailedException("Connecting failed", exception);
}
if (! await _AuthenticatePlainAsync(connection.Username, password).ConfigureAwait(false))
{
await Disconnect().ConfigureAwait(false);
throw new AuthenticatingFailedException();
}
_CurrentConnection = new Connection_Plain(connection)
{
Password = password,
};
await _ConnectionStorage.UpdateConnectionTimestamp(_CurrentConnection).ConfigureAwait(false);
}
/// <summary>
/// Connects to Server with Password
/// Connection is saved to Storage if connecting was successfuss
/// </summary>
/// <exception cref="AllreadyConnectedException"></exception>
/// <exception cref="MissingCredentialsException"></exception>
/// <exception cref="ConnectingFailedException"></exception>
/// <exception cref="AuthenticatingFailedException"></exception>
public async Task Connect(Connection connection, string password)
{
if (IsConnected)
{
throw new AllreadyConnectedException();
}
try
{
TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
_APIConnection = new FabAccessAPI.Connection(rpcClient);
}
catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
{
throw new ConnectingFailedException("Connecting failed", exception);
}
if (!await _AuthenticatePlainAsync(connection.Username, password).ConfigureAwait(false))
{
await Disconnect().ConfigureAwait(false);
throw new AuthenticatingFailedException();
}
_CurrentConnection = new Connection_Plain(connection)
{
Password = password,
};
try
{
await _ConnectionStorage.AddConnection(_CurrentConnection).ConfigureAwait(false);
}
catch(DuplicateConnectionException)
{
}
await _ConnectionCredentialStorage.AddCredentials(_CurrentConnection, password).ConfigureAwait(false);
await _ConnectionStorage.UpdateConnectionTimestamp(_CurrentConnection).ConfigureAwait(false);
}
/// <summary>
/// Reconnects to server if connection has lost
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
/// <exception cref="ReconnectingFailedException"></exception>
public async Task Reconnect()
{
if (IsConnected || _CurrentConnection == null)
{
throw new InvalidOperationException();
}
try
{
TcpRpcClient rpcClient = await _ConnectAsync(_CurrentConnection.Address.Host, _CurrentConnection.Address.Port).ConfigureAwait(false);
_APIConnection = new FabAccessAPI.Connection(rpcClient);
}
catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
{
throw new ReconnectingFailedException("Connecting failed", new ConnectingFailedException("Connecting failed", exception));
}
if (! await _AuthenticatePlainAsync(_CurrentConnection.Username, _CurrentConnection.Password).ConfigureAwait(false))
{
throw new ReconnectingFailedException("Authentication failed", new AuthenticatingFailedException());
}
}
/// <summary>
/// Disconnects from Server
/// </summary>
/// <returns></returns>
public Task Disconnect()
{
if (IsConnected)
{
_APIConnection.RpcClient?.Dispose();
}
_APIConnection = null;
_CurrentConnection = null;
return Task.CompletedTask;
}
#region FabAccess API Systems
public async Task<Session> GetSession()
{
if (!IsConnected)
{
await Reconnect().ConfigureAwait(false);
}
return _APIConnection.Session;
}
#endregion
#endregion
#region Private Methods
private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
private async Task<TcpRpcClient> _ConnectAsync(string host, int port)
{
TcpRpcClient rpcClient = new TcpRpcClient();
rpcClient.InjectMidlayer((tcpstream) =>
{
var sslStream = new SslStream(tcpstream, false, new RemoteCertificateValidationCallback(RemoteCertificateValidationCallback));
try
{
sslStream.AuthenticateAsClient("bffhd");
return sslStream;
}
catch (AuthenticationException)
{
sslStream.Close();
throw;
}
});
rpcClient.Connect(host, port);
await rpcClient.WhenConnected.ConfigureAwait(false);
return rpcClient;
}
private async Task<bool> _AuthenticatePlainAsync(string username, string password)
{
try
{
await _APIConnection.Auth("PLAIN", new Dictionary<string, object>(StringComparer.Ordinal) { { "Username", username }, { "Password", password } }).ConfigureAwait(false);
return await Task.FromResult(true).ConfigureAwait(false);
}
catch(InvalidCredentialsException)
{
return await Task.FromResult(true).ConfigureAwait(false);
}
catch (AuthenticatingFailedException)
{
return await Task.FromResult(true).ConfigureAwait(false);
}
}
#endregion
}
}

View File

@ -1,22 +0,0 @@
using System;
namespace Borepin.Service.BFFH.Exceptions
{
public class AllreadyConnectedException : Exception
{
public AllreadyConnectedException()
{
}
public AllreadyConnectedException(string message) : base(message)
{
}
public AllreadyConnectedException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,22 +0,0 @@
using System;
namespace Borepin.Service.BFFH.Exceptions
{
public class AuthenticatingFailedException : Exception
{
public AuthenticatingFailedException()
{
}
public AuthenticatingFailedException(string message) : base(message)
{
}
public AuthenticatingFailedException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,22 +0,0 @@
using System;
namespace Borepin.Service.BFFH.Exceptions
{
public class MissingCredentialsException : Exception
{
public MissingCredentialsException()
{
}
public MissingCredentialsException(string message) : base(message)
{
}
public MissingCredentialsException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,27 +0,0 @@
using Borepin.Model;
using FabAccessAPI.Schema;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Borepin.Service.BFFH
{
public interface IBFFHService
{
Connection CurrentConnection { get; }
bool IsConnected { get; }
Task<IList<Connection>> GetConnections();
Task RemoveConnection(Connection connection);
Task<bool> TestConnection(Connection connection);
Task Connect(Connection connection);
Task Connect(Connection connection, string password);
Task Reconnect();
Task Disconnect();
Task<Session> GetSession();
}
}

View File

@ -0,0 +1,9 @@
using FabAccessAPI;
namespace Borepin.Service
{
public interface IAPIService
{
IAPI GetAPI();
}
}

View File

@ -1,22 +1,24 @@
using System; using FabAccessAPI;
using System;
namespace Borepin.Service.Storage.Exceptions namespace Borepin.Service.Storage.Exceptions
{ {
public class DuplicateConnectionException : Exception public class DuplicateConnectionException : Exception
{ {
public DuplicateConnectionException() public readonly ConnectionData ConnectionData;
public DuplicateConnectionException(ConnectionData connectionData)
{ {
ConnectionData = connectionData;
} }
public DuplicateConnectionException(string message) : base(message) public DuplicateConnectionException(ConnectionData connectionData, string message) : base(message)
{ {
ConnectionData = connectionData;
} }
public DuplicateConnectionException(string message, Exception inner) : base(message, inner) public DuplicateConnectionException(ConnectionData connectionData, string message, Exception inner) : base(message, inner)
{ {
ConnectionData = connectionData;
} }
} }
} }

View File

@ -0,0 +1,26 @@
using FabAccessAPI;
using System;
namespace Borepin.Service.Storage.Exceptions
{
[Serializable]
internal class InvalidConnectionExceptoin : Exception
{
public readonly ConnectionData ConnectionData;
public InvalidConnectionExceptoin(ConnectionData connectionData)
{
ConnectionData = connectionData;
}
public InvalidConnectionExceptoin(ConnectionData connectionData, string message) : base(message)
{
ConnectionData = connectionData;
}
public InvalidConnectionExceptoin(ConnectionData connectionData, string message, Exception innerException) : base(message, innerException)
{
ConnectionData = connectionData;
}
}
}

View File

@ -1,22 +1,24 @@
using System; using FabAccessAPI;
using System;
namespace Borepin.Service.Storage.Exceptions namespace Borepin.Service.Storage.Exceptions
{ {
public class MissingConnectionException : Exception public class MissingConnectionException : Exception
{ {
public MissingConnectionException() public readonly ConnectionData ConnectionData;
public MissingConnectionException(ConnectionData connectionData)
{ {
ConnectionData = connectionData;
} }
public MissingConnectionException(string message) : base(message) public MissingConnectionException(ConnectionData connectionData, string message) : base(message)
{ {
ConnectionData = connectionData;
} }
public MissingConnectionException(string message, Exception inner) : base(message, inner) public MissingConnectionException(ConnectionData connectionData, string message, Exception inner) : base(message, inner)
{ {
ConnectionData = connectionData;
} }
} }
} }

View File

@ -0,0 +1,18 @@
using FabAccessAPI;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Borepin.Service.Storage
{
public interface ILoginStorageService
{
Task<IList<ConnectionData>> GetList();
Task Add(ConnectionData connectionData);
Task Remove(ConnectionData connectionData);
Task UpdateTimestamp(ConnectionData connectionData);
Task<ConnectionData> GetDefault();
Task SetDefault(ConnectionData connectionData);
Task RemoveDefault();
}
}

View File

@ -0,0 +1,158 @@
using Borepin.Service.Storage.Exceptions;
using FabAccessAPI;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Borepin.Service.Storage
{
public class LoginStorageService : ILoginStorageService
{
#region Static Members
const string StorageKey_ConnectionDataList = "ConnectionData";
const string StorageKey_ConnecitonData_AutoConnect = "ConnectionData_Default";
#endregion
#region Private Members
private readonly ISecretStorageService _SecretStorageService;
#endregion
#region Constructors
public LoginStorageService(ISecretStorageService secretStorageService)
{
_SecretStorageService = secretStorageService;
}
#endregion
#region Methods
public async Task<IList<ConnectionData>> GetList()
{
return await _LoadConnectionData().ConfigureAwait(false);
}
public async Task Add(ConnectionData connectionData)
{
if (connectionData.Host.Host == string.Empty || connectionData.Username == string.Empty)
{
throw new InvalidConnectionExceptoin(connectionData);
}
IList<ConnectionData> connectionData_List = await _LoadConnectionData().ConfigureAwait(false);
if(connectionData_List.Contains(connectionData))
{
throw new DuplicateConnectionException(connectionData);
}
connectionData_List.Add(connectionData);
await _SaveConnectionData(connectionData_List).ConfigureAwait(false);
}
public async Task Remove(ConnectionData connectionData)
{
if (connectionData.Host.Host == string.Empty || connectionData.Username == string.Empty)
{
throw new InvalidConnectionExceptoin(connectionData);
}
List<ConnectionData> connectionData_List = new List<ConnectionData>(await _LoadConnectionData().ConfigureAwait(false));
if (!connectionData_List.Contains(connectionData))
{
throw new MissingConnectionException(connectionData);
}
connectionData_List.Remove(connectionData);
await _SaveConnectionData(connectionData_List).ConfigureAwait(false);
ConnectionData connectionData_default = await GetDefault().ConfigureAwait(false);
if (connectionData_default != null && connectionData_default.Equals(connectionData))
{
await RemoveDefault().ConfigureAwait(false);
}
}
public async Task UpdateTimestamp(ConnectionData connectionData)
{
if (connectionData.Host.Host == string.Empty || connectionData.Username == string.Empty)
{
throw new InvalidConnectionExceptoin(connectionData);
}
List<ConnectionData> connectionData_List = new List<ConnectionData>(await _LoadConnectionData().ConfigureAwait(false));
if (! connectionData_List.Contains(connectionData))
{
throw new MissingConnectionException(connectionData);
}
connectionData.LastTime = DateTime.UtcNow;
connectionData_List.Remove(connectionData);
connectionData_List.Add(connectionData);
await _SaveConnectionData(connectionData_List).ConfigureAwait(false);
}
public async Task<ConnectionData> GetDefault()
{
try
{
string data = await _SecretStorageService.GetAsync(StorageKey_ConnecitonData_AutoConnect).ConfigureAwait(false);
if (data != null)
{
ConnectionData connectionData = JsonConvert.DeserializeObject<ConnectionData>(data);
return connectionData;
}
return null;
}
catch (JsonSerializationException)
{
_SecretStorageService.Remove(StorageKey_ConnecitonData_AutoConnect);
return null;
}
}
public async Task SetDefault(ConnectionData connectionData)
{
string data = JsonConvert.SerializeObject(connectionData);
await _SecretStorageService.SetAsync(StorageKey_ConnecitonData_AutoConnect, data).ConfigureAwait(false);
}
public async Task RemoveDefault()
{
string data = JsonConvert.SerializeObject(null);
await _SecretStorageService.SetAsync(StorageKey_ConnecitonData_AutoConnect, data).ConfigureAwait(false);
}
#endregion
#region Private Methods
private async Task<IList<ConnectionData>> _LoadConnectionData()
{
List<ConnectionData> connectionData_List;
try
{
string data = await _SecretStorageService.GetAsync(StorageKey_ConnectionDataList).ConfigureAwait(false);
if(data != null)
{
connectionData_List = JsonConvert.DeserializeObject<List<ConnectionData>>(data);
}
else
{
connectionData_List = new List<ConnectionData>();
await _SecretStorageService.SetAsync(StorageKey_ConnectionDataList, JsonConvert.SerializeObject(connectionData_List)).ConfigureAwait(false);
}
}
catch (JsonSerializationException)
{
connectionData_List = new List<ConnectionData>();
await _SecretStorageService.SetAsync(StorageKey_ConnectionDataList, JsonConvert.SerializeObject(connectionData_List)).ConfigureAwait(false);
}
return connectionData_List;
}
private async Task _SaveConnectionData(IList<ConnectionData> connectionData_List)
{
string data = JsonConvert.SerializeObject(connectionData_List);
await _SecretStorageService.SetAsync(StorageKey_ConnectionDataList, data).ConfigureAwait(false);
}
#endregion
}
}

View File

@ -64,6 +64,11 @@
<Setter Property="HorizontalOptions" Value="CenterAndExpand"/> <Setter Property="HorizontalOptions" Value="CenterAndExpand"/>
</Style> </Style>
<Style x:Key="Style_Label_Text" TargetType="Label">
<Setter Property="Margin" Value="0, 0, 0, 10"/>
<Setter Property="HorizontalOptions" Value="StartAndExpand"/>
</Style>
<Style x:Key="Style_Label_Property_Title" TargetType="Label"> <Style x:Key="Style_Label_Property_Title" TargetType="Label">
<Setter Property="FontSize" Value="Default"/> <Setter Property="FontSize" Value="Default"/>
<Setter Property="FontAttributes" Value="Bold"/> <Setter Property="FontAttributes" Value="Bold"/>

View File

@ -2,7 +2,6 @@
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.View.MachineListItemView" x:Class="Borepin.View.MachineListItemView"
xmlns:pagemodel="clr-namespace:Borepin.PageModel"
xmlns:converters="clr-namespace:Borepin.Converter"> xmlns:converters="clr-namespace:Borepin.Converter">
<ContentView.Resources> <ContentView.Resources>
<ResourceDictionary> <ResourceDictionary>
@ -23,12 +22,12 @@
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="1"/> <RowDefinition Height="1"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Name}" Style="{StaticResource LabelStyle_Primary}"/> <Label Grid.Row="0" Grid.Column="1" Text="{Binding Machine.Name}" Style="{StaticResource LabelStyle_Primary}"/>
<StackLayout Grid.Row="0" Grid.Column="2" Orientation="Horizontal" HorizontalOptions="End"> <StackLayout Grid.Row="0" Grid.Column="2" Orientation="Horizontal" HorizontalOptions="End">
<Label Text="{Binding State, Converter={StaticResource MachineStateStringConverter}}" TextColor="{Binding State, Converter={StaticResource MachineStateColorConverter}}" Style="{StaticResource LabelStyle_Second}"/> <Label Text="{Binding Machine.State, Converter={StaticResource MachineStateStringConverter}}" TextColor="{Binding Machine.State, Converter={StaticResource MachineStateColorConverter}}" Style="{StaticResource LabelStyle_Second}"/>
<Label Text="by Me" IsVisible="{Binding IsUserAssigned}" Style="{StaticResource LabelStyle_Second}"/> <Label Text="by Me" IsVisible="{Binding IsInUseByMe}" Style="{StaticResource LabelStyle_Second}"/>
</StackLayout> </StackLayout>
<Button Grid.Row="0" Grid.Column="3" Margin="0, 3, 0, 3" Text="➔" Command="{Binding Source={RelativeSource AncestorType={x:Type pagemodel:MachineListPageModel}}, Path=SelectInstanceCommand}" CommandParameter="{Binding .}" Style="{StaticResource Style_Button_Primary}"/> <Button Grid.Row="0" Grid.Column="3" Margin="0, 3, 0, 3" Text="➔" Command="{Binding SelectInstanceCommand}" Style="{StaticResource Style_Button_Primary}"/>
<BoxView Grid.Row="1" Grid.ColumnSpan="5" BackgroundColor="{StaticResource FifthColor}"/> <BoxView Grid.Row="1" Grid.ColumnSpan="5" BackgroundColor="{StaticResource FifthColor}"/>
</Grid> </Grid>
</ContentView.Content> </ContentView.Content>

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.View.ServerListItemView" x:Class="Borepin.View.ServerListItemView">
xmlns:pagemodel="clr-namespace:Borepin.PageModel">
<ContentView.Content> <ContentView.Content>
<Grid RowSpacing="0"> <Grid RowSpacing="0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -16,9 +15,9 @@
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="1"/> <RowDefinition Height="1"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Address, StringFormat='{0}'}" Style="{StaticResource LabelStyle_Primary}" VerticalOptions="Center"/> <Label Grid.Row="0" Grid.Column="1" Text="{Binding ConnectionData.Host, StringFormat='{0}'}" Style="{StaticResource LabelStyle_Primary}" VerticalOptions="Center"/>
<Label Grid.Row="0" Grid.Column="2" Text="{Binding Username}" Style="{StaticResource LabelStyle_Second}" HorizontalTextAlignment="End" VerticalOptions="Center"/> <Label Grid.Row="0" Grid.Column="2" Text="{Binding ConnectionData.Username}" Style="{StaticResource LabelStyle_Second}" HorizontalTextAlignment="End" VerticalOptions="Center"/>
<Button Grid.Row="0" Grid.Column="3" Margin="0, 3, 0, 3" Text="➔" Command="{Binding Source={RelativeSource AncestorType={x:Type pagemodel:ServerListPageModel}}, Path=SelectInstanceCommand}" CommandParameter="{Binding .}" Style="{StaticResource Style_Button_Primary}" VerticalOptions="Center"/> <Button Grid.Row="0" Grid.Column="3" Margin="0, 3, 0, 3" Text="➔" Command="{Binding SelectInstanceCommand}" Style="{StaticResource Style_Button_Primary}" VerticalOptions="Center"/>
<BoxView Grid.Row="1" Grid.ColumnSpan="5" BackgroundColor="{StaticResource FifthColor}"/> <BoxView Grid.Row="1" Grid.ColumnSpan="5" BackgroundColor="{StaticResource FifthColor}"/>
</Grid> </Grid>
</ContentView.Content> </ContentView.Content>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.View.UserListItemView">
<ContentView.Content>
<Grid RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding User.Username, StringFormat='{0}'}" Style="{StaticResource LabelStyle_Primary}" VerticalOptions="Center"/>
<Button Grid.Row="0" Grid.Column="3" Margin="0, 3, 0, 3" Text="➔" Command="{Binding SelectInstanceCommand}" Style="{StaticResource Style_Button_Primary}" VerticalOptions="Center"/>
<BoxView Grid.Row="1" Grid.ColumnSpan="5" BackgroundColor="{StaticResource FifthColor}"/>
</Grid>
</ContentView.Content>
</ContentView>

View File

@ -0,0 +1,15 @@

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class UserListItemView : ContentView
{
public UserListItemView()
{
InitializeComponent();
}
}
}

View File

@ -1,44 +1,77 @@
using Prism.Mvvm; using FabAccessAPI.Schema;
using FabAccessAPI.Schema; using System.Threading.Tasks;
using System.Windows.Input;
using Borepin.Base;
using Prism.Navigation;
using Prism.Services;
using Prism.Commands;
using Xamarin.Forms;
using Borepin.Model;
namespace Borepin.ViewModel namespace Borepin.ViewModel
{ {
public class MachineListItemViewModel : BindableBase public class MachineListItemViewModel : PageModelBase
{ {
public MachineListItemViewModel(Machine instance) #region Constructors
public MachineListItemViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{ {
_Instance = instance; SelectInstanceCommand = new DelegateCommand(SelectInstanceCommandExecute);
}
#endregion
Name = instance.Name; #region LoadData
State = instance.State; public override Task LoadInstance(object instance)
{
if(instance is Machine)
{
Machine = new MachineVisualize(instance as Machine);
Machine.LoadData();
}
return Task.CompletedTask;
}
#endregion
#region Commands
private ICommand _SelectInstanceCommand;
public ICommand SelectInstanceCommand
{
get => _SelectInstanceCommand;
set => SetProperty(ref _SelectInstanceCommand, value);
}
public void SelectInstanceCommandExecute()
{
NavigationParameters parameters = new NavigationParameters
{
{ "instance", Machine._Machine.Id },
};
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage/MachinePage", parameters).ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
private Machine _Instance; #endregion
public Machine Instance
#region Fields
private MachineVisualize _Machine;
public MachineVisualize Machine
{ {
get => _Instance; get => _Machine;
set => SetProperty(ref _Instance, value); set => SetProperty(ref _Machine, value);
} }
private string _Name; private bool _IsInUseByMe = false;
public string Name public bool IsInUseByMe
{ {
get => _Name; get => _IsInUseByMe;
set => SetProperty(ref _Name, value); set => SetProperty(ref _IsInUseByMe, value);
}
private Machine.MachineState _State;
public Machine.MachineState State
{
get => _State;
set => SetProperty(ref _State, value);
}
private bool _IsUserAssigned = false;
public bool IsUserAssigned
{
get => _IsUserAssigned;
set => SetProperty(ref _IsUserAssigned, value);
} }
#endregion
} }
} }

View File

@ -1,34 +1,69 @@
using Borepin.Model; using Borepin.Base;
using Prism.Mvvm; using Borepin.Model;
using FabAccessAPI;
using Prism.Commands;
using Prism.Navigation;
using Prism.Services;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.ViewModel namespace Borepin.ViewModel
{ {
public class ServerListItemViewModel : BindableBase public class ServerListItemViewModel : PageModelBase
{ {
#region Constructors #region Constructors
public ServerListItemViewModel(Connection instance) public ServerListItemViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{ {
Instance = instance; SelectInstanceCommand = new DelegateCommand(SelectInstanceCommandExecute);
Address = instance.Address.Host; }
Username = instance.Username; #endregion
#region LoadData
public override Task LoadInstance(object instance)
{
if(instance is ConnectionData)
{
ConnectionData = new ConnectionDataVisualize(instance as ConnectionData);
ConnectionData.LoadData();
}
return Task.CompletedTask;
} }
#endregion #endregion
#region Fields #region Fields
public readonly Connection Instance; public readonly ConnectionData Instance;
private string _Address; private ConnectionDataVisualize _ConnectionData;
public string Address public ConnectionDataVisualize ConnectionData
{ {
get => _Address; get => _ConnectionData;
set => SetProperty(ref _Address, value); set => SetProperty(ref _ConnectionData, value);
} }
#endregion
private string _Username; #region Commands
public string Username private ICommand _SelectInstanceCommand;
public ICommand SelectInstanceCommand
{ {
get => _Username; get => _SelectInstanceCommand;
set => SetProperty(ref _Username, value); set => SetProperty(ref _SelectInstanceCommand, value);
}
public void SelectInstanceCommandExecute()
{
NavigationParameters parameters = new NavigationParameters
{
{ "instance", ConnectionData._ConnectionData },
};
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage/ServerPage", parameters).ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
} }
#endregion #endregion
} }

View File

@ -0,0 +1,71 @@
using Borepin.Base;
using Borepin.Model;
using FabAccessAPI;
using FabAccessAPI.Schema;
using Prism.Commands;
using Prism.Navigation;
using Prism.Services;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.ViewModel
{
public class UserListItemViewModel : PageModelBase
{
#region Constructors
public UserListItemViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService)
{
SelectInstanceCommand = new DelegateCommand(SelectInstanceCommandExecute);
}
#endregion
#region LoadData
public override Task LoadInstance(object instance)
{
if(instance is User)
{
User = new UserVisualize(instance as User);
User.LoadData();
}
return Task.CompletedTask;
}
#endregion
#region Fields
public readonly User Instance;
private UserVisualize _User;
public UserVisualize User
{
get => _User;
set => SetProperty(ref _User, value);
}
#endregion
#region Commands
private ICommand _SelectInstanceCommand;
public ICommand SelectInstanceCommand
{
get => _SelectInstanceCommand;
set => SetProperty(ref _SelectInstanceCommand, value);
}
public void SelectInstanceCommandExecute()
{
NavigationParameters parameters = new NavigationParameters
{
{ "instance", User.Username },
};
Device.BeginInvokeOnMainThread(async () =>
{
INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/UserListPage/UserPage", parameters).ConfigureAwait(false);
if (result.Exception != null)
{
Log.Fatal(result.Exception, "Navigating failed");
}
});
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More