Add Code for v0.2.2

This commit is contained in:
TheJoKlLa 2022-01-03 21:13:03 +00:00
parent f14dab06c4
commit 8be154ab7a
123 changed files with 7334 additions and 2120 deletions

4
.editorconfig Normal file
View File

@ -0,0 +1,4 @@
[*.cs]
# MA0003: Add argument name to improve readability
dotnet_diagnostic.MA0003.severity = none

View File

@ -1,236 +1,310 @@
# This file is a template, and might need editing before it works on your project.
# The following script will work for any project that can be built from command line by msbuild
# It uses powershell shell executor, so you need to add the following line to your config.toml file
# (located in gitlab-runner.exe directory):
# shell = "powershell"
#
# The script is composed of 3 stages: build, test and deploy.
#
# The build stage restores NuGet packages and uses msbuild to build the exe and msi
# One major issue you'll find is that you can't build msi projects from command line
# if you use vdproj. There are workarounds building msi via devenv, but they rarely work
# The best solution is migrating your vdproj projects to WiX, as it can be build directly
# by msbuild.
#
# The test stage runs nunit from command line against Test project inside your solution
# It also saves the resulting TestResult.xml file
#
# The deploy stage copies the exe and msi from build stage to a network drive
# You need to have the network drive mapped as Local System user for gitlab-runner service to see it
# The best way to persist the mapping is via a scheduled task (see: https://stackoverflow.com/a/7867064/1288473),
# running the following batch command: net use P: \\x.x.x.x\Projects /u:your_user your_pass /persistent:yes
# place project specific paths in variables to make the rest of the script more generic
variables:
VERSION_PATTERN: '/v\d+\.\d+(\.\d+)?/'
GIT_SUBMODULE_STRATEGY: recursive
LIB_RELEASE_FOLDER: 'Borepin\Borepin\bin\Release'
UWP_RELEASE_FOLDER: 'Borepin\Borepin.UWP\bin\x86\Release'
TEST_FOLDER: 'Tests\bin\Release'
# DEPLOY_FOLDER: 'P:\Projects\YourApp\Builds'
NUGET_PATH: 'C:\ProgramData\chocolatey\bin\nuget.exe'
DOTNET_PATH: 'C:\Program Files\dotnet\dotnet.exe'
MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe'
NUNIT_PATH: 'C:\ProgramData\chocolatey\bin\nunit3-console.exe'
WIN_NUGET_PATH: 'C:\ProgramData\chocolatey\bin\nuget.exe'
WIN_MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\msbuild.exe'
WIN_NUNIT_PATH: 'C:\ProgramData\chocolatey\bin\nunit3-console.exe'
stages:
- build
- test
- pack
- deploy
build_base:
build_Base:
stage: build
tags:
- xamarin
- fabinfra
- public
- windows
# only:
# - tags # the build process will only be started by git tag commits
script:
- '& "$env:NUGET_PATH" restore' # restore Nuget dependencies
- '& "$env:MSBUILD_PATH" /p:Configuration=Release /target:Restore /target:Borepin' # build the project
artifacts:
expire_in: 1 week # save gitlab server space, we copy the files we need to deploy folder later on
paths:
- '$env:LIB_RELEASE_FOLDER' # saving exe to copy to deploy folder
# - '$env:TEST_FOLDER\' # saving entire Test project so NUnit can run tests
build_UWP:
needs:
- build_base
stage: build
tags:
- powershell
- xamarin
- windows
# only:
# - tags # the build process will only be started by git tag commits
script:
- '& "$env:NUGET_PATH" restore' # restore Nuget dependencies
- '& "$env:MSBUILD_PATH" /p:Configuration=Debug /target:Borepin_UWP' # build the project
# artifacts:
# expire_in: 1 week # save gitlab server space, we copy the files we need to deploy folder later on
# paths:
# - '$env:UWP_RELEASE_FOLDER' # saving exe to copy to deploy folder
# - '$env:TEST_FOLDER\' # saving entire Test project so NUnit can run tests
- '& "$WIN_NUGET_PATH" restore'
- '& "$WIN_MSBUILD_PATH" /t:Restore /p:Configuration=Debug /t:Borepin'
build_Android:
needs:
- build_base
stage: build
needs:
- build_Base
tags:
- xamarin
- fabinfra
- public
- windows
# only:
# - tags # the build process will only be started by git tag commits
- powershell
- xamarin
script:
- '& "$env:NUGET_PATH" restore' # restore Nuget dependencies
- '[System.IO.File]::WriteAllBytes("$(pwd)/fabaccess.keystore", [System.Convert]::FromBase64String($AndroidKeyStore))'
- '& "$env:MSBUILD_PATH" /p:Configuration=Release /target:Borepin_Android:PackageForAndroid /target:Borepin_Android:SignAndroidPackage /p:AndroidKeyStore="True" /p:AndroidSigningKeyStore="$(pwd)/fabaccess.keystore" /p:AndroidSigningKeyPass="$AndroidKeyStore_Password" /p:AndroidSigningKeyAlias="$AndroidKeyStore_ID" /p:AndroidSigningStorePass="$AndroidKeyStore_Password"' # build the project
- rm "$(pwd)/fabaccess.keystore"
artifacts:
expire_in: 1 week # save gitlab server space, we copy the files we need to deploy folder later on
paths:
- Borepin/Borepin.Android/bin/Release/org.fab_infra.fabaccess-Signed.aab # saving apk to copy to deploy folder
#- Borepin/Borepin.Android/bin/Release/
# - '$env:TEST_FOLDER\' # saving entire Test project so NUnit can run tests
- '& "$WIN_NUGET_PATH" restore'
- '& "$WIN_MSBUILD_PATH" /t:Restore /p:Configuration=Debug /t:Borepin_Android'
build_UWP:
stage: build
needs:
- build_Base
tags:
- fabinfra
- public
- windows
- powershell
- xamarin
script:
- '& "$WIN_NUGET_PATH" restore'
- '& "$WIN_MSBUILD_PATH" /t:Restore /p:Configuration=Debug /t:Borepin_UWP'
build_iOS:
needs:
- build_base
stage: build
needs:
- build_Base
tags:
- fabinfra
- public
- macos
# only:
# - tags # the build process will only be started by git tag commits
- shell
- xamarin
script:
- 'nuget restore' # restore Nuget dependencies
- 'nuget restore'
- 'msbuild /t:Restore'
- 'msbuild /t:Borepin_iOS /p:Configuration=Debug /p:Platform=iPhone /p:ArchiveOnBuild=true /p:BuildIpa=true' # build the project /p:AndroidKeyStore=True
artifacts:
expire_in: 1 week # save gitlab server space, we copy the files we need to deploy folder later on
paths:
- Borepin/Borepin.iOS/bin/iPhone/Debug/Borepin.iOS.ipa
#- Borepin/Borepin.iOS/bin/iPhone/Debug/
# - '$env:TEST_FOLDER\' # saving entire Test project so NUnit can run tests
- 'msbuild /p:Configuration=Debug /t:Borepin_iOS'
build_GTK:
needs:
- build_base
stage: build
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
needs:
- build_Base
tags:
- docker
# only:
# - tags # the build process will only be started by git tag commits
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
script:
- 'nuget restore' # restore Nuget dependencies
- 'msbuild -t:Borepin_GTK' # build the project /p:AndroidKeyStore=True
- 'nuget restore'
- 'msbuild -t:Restore'
- 'msbuild -p:Configuration=Debug -t:Borepin_GTK'
pack_Android_AAB:
stage: pack
needs:
- build_Android
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
tags:
- fabinfra
- internal
- windows
- powershell
- xamarin
before_script:
- '$Env:VERSION_NUMBER="$CI_COMMIT_TAG".SubString(1)'
- '$Env:BUILD_NUMBER="$CI_PIPELINE_ID"'
script:
- '& "$WIN_NUGET_PATH" restore'
- '[System.IO.File]::WriteAllBytes("$(pwd)/fabaccess.keystore", [System.Convert]::FromBase64String($AndroidKeyStore))'
- '& "$WIN_MSBUILD_PATH" /t:Restore /t:Borepin_Android:SetVersion /p:Configuration=Release /target:Borepin_Android:PackageForAndroid /target:Borepin_Android:SignAndroidPackage /p:AndroidKeyStore="True" /p:AndroidSigningKeyStore="$(pwd)/fabaccess.keystore" /p:AndroidSigningKeyPass="$AndroidKeyStore_Password" /p:AndroidSigningKeyAlias="$AndroidKeyStore_ID" /p:AndroidSigningStorePass="$AndroidKeyStore_Password"'
- 'rm "$(pwd)/fabaccess.keystore"'
artifacts:
expire_in: 1 week # save gitlab server space, we copy the files we need to deploy folder later on
expire_in: 1 week
paths:
- Borepin/Borepin.GTK/bin/Debug/
- Borepin/Borepin.Android/bin/Release/org.fab_infra.fabaccess-Signed.aab
# test_job:
# stage: test
# tags:
# - xamarin
# - windows
# # only:
# # - tags
# script:
# - '& "$env:NUNIT_PATH" ".\$env:TEST_FOLDER\Tests.dll"' # running NUnit tests
# artifacts:
# when: always # save test results even when the task fails
# expire_in: 1 week # save gitlab server space, we copy the files we need to deploy folder later on
# paths:
# - '.\TestResult.xml' # saving NUnit results to copy to deploy folder
# dependencies:
# - build_job
pack_Android_APK:
stage: pack
needs:
- build_Android
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
tags:
- fabinfra
- internal
- windows
- powershell
- xamarin
before_script:
- '$Env:VERSION_NUMBER="$CI_COMMIT_TAG".SubString(1)'
- '$Env:BUILD_NUMBER="$CI_PIPELINE_ID"'
- '$Env:ANDROID_PKG_FORMAT="apk"'
script:
- '& "$WIN_NUGET_PATH" restore'
- '[System.IO.File]::WriteAllBytes("$(pwd)/fabaccess.keystore", [System.Convert]::FromBase64String($AndroidKeyStore))'
- '& "$WIN_MSBUILD_PATH" /t:Restore /t:Borepin_Android:SetVersion /p:Configuration=Release /target:Borepin_Android /target:Borepin_Android:SignAndroidPackage /p:AndroidKeyStore="True" /p:AndroidSigningKeyStore="$(pwd)/fabaccess.keystore" /p:AndroidSigningKeyPass="$AndroidKeyStore_Password" /p:AndroidSigningKeyAlias="$AndroidKeyStore_ID" /p:AndroidSigningStorePass="$AndroidKeyStore_Password"'
- 'rm "$(pwd)/fabaccess.keystore"'
artifacts:
expire_in: 1 week
paths:
- Borepin/Borepin.Android/bin/Release/org.fab_infra.fabaccess-Signed.apk
deploy_Android_alpha:
pack_iOS:
stage: pack
needs:
- build_iOS
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
tags:
- fabinfra
- internal
- macos
- shell
- xamarin
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
script:
- 'nuget restore'
- 'msbuild /t:Restore'
- 'msbuild /t:Borepin_iOS:SetVersion /t:Borepin_iOS /p:Configuration=Release /p:Platform=iPhone /p:ArchiveOnBuild=true /p:BuildIpa=true'
artifacts:
expire_in: 1 week
paths:
- Borepin/Borepin.iOS/bin/iPhone/Release/Borepin.iOS.ipa
deploy_Android_Internal:
stage: deploy
needs:
- pack_Android_AAB
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
tags:
- docker
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
variables:
LC_ALL: 'en_US.UTF-8'
LANG: 'en_US.UTF-8'
only:
- alpha
needs:
- build_Android
stage: deploy
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
tags:
- docker
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
- 'echo $play_store_credentials > play-store-credentials.json'
script:
- 'bundle install'
- 'bundle exec fastlane supply --aab Borepin/Borepin.Android/bin/Release/org.fab_infra.fabaccess-Signed.aab --track internal'
after_script:
- 'rm play-store-credentials.json'
dependencies:
- build_Android
deploy_Android_beta:
deploy_Android_Beta:
stage: deploy
needs:
- deploy_Android_Internal
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
when: manual
tags:
- docker
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
variables:
LC_ALL: 'en_US.UTF-8'
LANG: 'en_US.UTF-8'
only:
- beta
needs:
- build_Android
stage: deploy
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
tags:
- docker
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
- 'echo $play_store_credentials > play-store-credentials.json'
script:
- 'bundle install'
- 'bundle exec fastlane supply --aab Borepin/Borepin.Android/bin/Release/org.fab_infra.fabaccess-Signed.aab --track beta'
- 'bundle exec fastlane supply --track internal --track_promote_to beta'
after_script:
- 'rm play-store-credentials.json'
dependencies:
- build_Android
deploy_iOS_alpha:
deploy_Android_Production:
stage: deploy
needs:
- deploy_Android_Beta
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
when: manual
tags:
- docker
image: registry.gitlab.com/fabinfra/gtk-sharp-build:latest
variables:
LC_ALL: 'en_US.UTF-8'
LANG: 'en_US.UTF-8'
only:
- alpha
needs:
- build_iOS
stage: deploy
tags:
- macos
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
- 'echo $play_store_credentials > play-store-credentials.json'
script:
- 'bundle install'
- 'bundle exec fastlane supply --track internal --track_promote_to production'
after_script:
- 'rm play-store-credentials.json'
deploy_iOS_Internal:
stage: deploy
needs:
- pack_iOS
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
tags:
- fabinfra
- internal
- macos
- shell
- xamarin
variables:
LC_ALL: 'en_US.UTF-8'
LANG: 'en_US.UTF-8'
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
- 'echo $app_store_credentials > app-store-credentials.json'
- 'export PATH="/usr/local/opt/ruby/bin:$PATH"'
script:
- 'bundle install'
- 'bundle update fastlane'
- 'bundle exec fastlane pilot upload --api_key_path app-store-credentials.json --ipa Borepin/Borepin.iOS/bin/iPhone/Debug/Borepin.iOS.ipa'
- 'bundle exec fastlane pilot upload --api_key_path app-store-credentials.json --ipa Borepin/Borepin.iOS/bin/iPhone/Release/Borepin.iOS.ipa'
after_script:
- 'rm app-store-credentials.json'
dependencies:
- build_iOS
deploy_iOS_beta:
deploy_iOS_Beta:
stage: deploy
needs:
- pack_iOS
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
when: manual
tags:
- fabinfra
- internal
- macos
- shell
- xamarin
variables:
LC_ALL: 'en_US.UTF-8'
LANG: 'en_US.UTF-8'
only:
- beta
needs:
- build_iOS
stage: deploy
tags:
- macos
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
- 'echo $app_store_credentials > app-store-credentials.json'
- 'export PATH="/usr/local/opt/ruby/bin:$PATH"'
script:
- 'bundle install'
- 'bundle update fastlane'
- 'bundle exec fastlane pilot upload --api_key_path app-store-credentials.json --ipa Borepin/Borepin.iOS/bin/iPhone/Debug/Borepin.iOS.ipa --distribute_external true --groups Beta --changelog "$CI_COMMIT_MESSAGE"'
- 'bundle exec fastlane pilot upload --api_key_path app-store-credentials.json --ipa Borepin/Borepin.iOS/bin/iPhone/Release/Borepin.iOS.ipa --distribute_external true --groups Beta --changelog "Bugfixes and/or new features"'
after_script:
- 'rm app-store-credentials.json'
deploy_iOS_Production:
stage: deploy
needs:
- deploy_iOS_Beta
rules:
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG =~ /v\d+\.\d+(\.\d+)?/
when: manual
tags:
- fabinfra
- internal
- macos
- shell
- xamarin
variables:
LC_ALL: 'en_US.UTF-8'
LANG: 'en_US.UTF-8'
before_script:
- 'export VERSION_NUMBER=${CI_COMMIT_TAG:1}'
- 'export BUILD_NUMBER="$CI_PIPELINE_ID"'
- 'echo $app_store_credentials > app-store-credentials.json'
- 'export PATH="/usr/local/opt/ruby/bin:$PATH"'
script:
- 'bundle install'
- 'bundle update fastlane'
- 'bundle exec fastlane deliver submit_build --build_number $BUILD_NUMBER --submit_for_review true --automatic_release true --force true --skip_metadata true --skip_screenshots true --skip_binary_upload true --api_key_path app-store-credentials.json'
after_script:
- 'rm app-store-credentials.json'
dependencies:
- build_iOS

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30413.136
VisualStudioVersion = 16.0.32002.261
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.UWP", "Borepin\Borepin.UWP\Borepin.UWP.csproj", "{664AA356-2920-4353-A80A-B89128011381}"
EndProject
@ -25,6 +25,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "external\NFC\NFC\NFC
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime", "external\capnproto-dotnetcore\Capnp.Net.Runtime\Capnp.Net.Runtime.csproj", "{C587AAC3-50A7-4871-A50D-7880B6F24EF6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Borepin_Test", "Borepin_Test\Borepin_Test.csproj", "{A959A406-91A5-4D81-B90D-EF022812D97D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0EA0AA4A-A814-45A0-9EA7-E9147CCCCB6A}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitlab-ci.yml = .gitlab-ci.yml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -353,6 +361,30 @@ Global
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x64.Build.0 = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x86.ActiveCfg = Release|Any CPU
{C587AAC3-50A7-4871-A50D-7880B6F24EF6}.Release|x86.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|ARM.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|iPhone.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|x64.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|x64.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|x86.ActiveCfg = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Debug|x86.Build.0 = Debug|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|Any CPU.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|ARM.ActiveCfg = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|ARM.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|iPhone.ActiveCfg = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|iPhone.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|x64.ActiveCfg = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|x64.Build.0 = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|x86.ActiveCfg = Release|Any CPU
{A959A406-91A5-4D81-B90D-EF022812D97D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -50,7 +50,8 @@
<AndroidSigningStorePass>
</AndroidSigningStorePass>
<AndroidCreatePackagePerAbi>false</AndroidCreatePackagePerAbi>
<AndroidPackageFormat>aab</AndroidPackageFormat>
<AndroidPackageFormat Condition="'$(ANDROID_PKG_FORMAT)' != ''">$(ANDROID_PKG_FORMAT)</AndroidPackageFormat>
<AndroidPackageFormat Condition="'$(ANDROID_PKG_FORMAT)' == ''">aab</AndroidPackageFormat>
<AndroidUseAapt2>true</AndroidUseAapt2>
</PropertyGroup>
<ItemGroup>
@ -66,7 +67,7 @@
<PackageReference Include="Prism.DryIoc.Forms">
<Version>8.1.97</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2125" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2291" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.0" />
</ItemGroup>
<ItemGroup>
@ -75,8 +76,8 @@
<Compile Include="PlatformInitializer.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\PreferenceService.cs" />
<Compile Include="Services\SecretService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorage.cs" />
<Compile Include="SplashActivity.cs" />
</ItemGroup>
<ItemGroup>
@ -183,8 +184,8 @@
<UserProperties TriggeredFromHotReload="False" />
</VisualStudio>
</ProjectExtensions>
<Target Name="BeforeBuild" Condition=" '$(GITLAB_CI)' == 'true' ">
<Target Name="SetVersion">
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="&lt;Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' /&gt;" Query="manifest/@android:versionCode" Value="$(CI_PIPELINE_ID)" />
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="&lt;Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' /&gt;" Query="manifest/@android:versionName" Value="$(CI_COMMIT_SHORT_SHA)-$(CI_PIPELINE_ID)" />
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="&lt;Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' /&gt;" Query="manifest/@android:versionName" Value="$(CI_COMMIT_TAG.SubString(1))" />
</Target>
</Project>

View File

@ -18,8 +18,18 @@ namespace Borepin.Droid
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App(new PlatformInitializer()));
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}

View File

@ -1,5 +1,5 @@
using Borepin.Droid.Services;
using Borepin.Service;
using Borepin.Service.Storage;
using Prism;
using Prism.Ioc;
@ -9,8 +9,8 @@ namespace Borepin.Droid
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IPreferenceService, PreferenceService>();
containerRegistry.Register<ISecretService, SecretService>();
containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>();
containerRegistry.Register<ISecretStorageService, SecretStorage>();
}
}
}

View File

@ -4,4 +4,6 @@
<application android:theme="@style/MainTheme" android:label="FabAccess" android:networkSecurityConfig="@xml/network_security_config"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
</manifest>

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
using Borepin.Service;
using Borepin.Service.Storage;
using Xamarin.Essentials;
namespace Borepin.Droid.Services
{
public class PreferenceService : IPreferenceService
public class PreferenceStorageService : IPreferenceStorageService
{
public void Clear()
{

View File

@ -1,10 +1,10 @@
using Borepin.Service;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Borepin.Service.Storage;
using Xamarin.Essentials;
namespace Borepin.Droid.Services
{
public class SecretService : ISecretService
public class SecretStorage : ISecretStorageService
{
public Task<string> GetAsync(string key)
{

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.props" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.props')" />
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -42,8 +42,8 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0\atk-sharp.dll</HintPath>
</Reference>
<Reference Include="DryIoc, Version=4.8.1.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL">
<HintPath>..\..\packages\DryIoc.dll.4.8.1\lib\net45\DryIoc.dll</HintPath>
<Reference Include="DryIoc, Version=4.8.4.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL">
<HintPath>..\..\packages\DryIoc.dll.4.8.4\lib\net45\DryIoc.dll</HintPath>
</Reference>
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -89,28 +89,32 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Xamarin.Forms.Core">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\netstandard2.0\Xamarin.Forms.Core.dll</HintPath>
<Reference Include="webkit-sharp, Version=1.1.15.0, Culture=neutral, PublicKeyToken=eaa1d335d2e19745, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.Platform.GTK.5.0.0.2291\lib\net45\webkit-sharp.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\netstandard2.0\Xamarin.Forms.Platform.dll</HintPath>
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\netstandard2.0\Xamarin.Forms.Core.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Xaml">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\netstandard2.0\Xamarin.Forms.Xaml.dll</HintPath>
<Reference Include="Xamarin.Forms.Platform, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\netstandard2.0\Xamarin.Forms.Platform.dll</HintPath>
</Reference>
<Reference Include="webkit-sharp">
<HintPath>..\..\packages\Xamarin.Forms.Platform.GTK.5.0.0.2125\lib\net45\webkit-sharp.dll</HintPath>
<Reference Include="Xamarin.Forms.Platform.GTK, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.Platform.GTK.5.0.0.2291\lib\net45\Xamarin.Forms.Platform.GTK.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform.GTK">
<HintPath>..\..\packages\Xamarin.Forms.Platform.GTK.5.0.0.2125\lib\net45\Xamarin.Forms.Platform.GTK.dll</HintPath>
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\netstandard2.0\Xamarin.Forms.Xaml.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="PlatformInitializer.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\.editorconfig">
<Link>.editorconfig</Link>
</None>
<None Include="app.config" />
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
@ -123,5 +127,12 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props'))" />
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets'))" />
</Target>
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets')" />
</Project>

View File

@ -0,0 +1,8 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE0060:Nicht verwendete Parameter entfernen", Justification = "<Ausstehend>", Scope = "member", Target = "~M:Borepin.GTK.MainClass.Main(System.String[])")]

View File

@ -12,7 +12,7 @@ namespace Borepin.GTK
Gtk.Application.Init();
Forms.Init();
var window = new FormsWindow();
FormsWindow window = new FormsWindow();
window.LoadApplication(new App(new PlatformInitializer()));
window.SetApplicationTitle("FabAccess");
window.Show();

View File

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

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DryIoc.dll" version="4.8.1" targetFramework="net48" />
<package id="DryIoc.dll" version="4.8.4" targetFramework="net48" />
<package id="OpenTK" version="3.2" 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.Forms" version="8.1.97" targetFramework="net48" />
<package id="Xamarin.Forms" version="5.0.0.2125" targetFramework="net48" />
<package id="Xamarin.Forms.Platform.GTK" version="5.0.0.2125" targetFramework="net48" />
<package id="Xamarin.Forms" version="5.0.0.2291" targetFramework="net48" />
<package id="Xamarin.Forms.Platform.GTK" version="5.0.0.2291" targetFramework="net48" />
</packages>

View File

@ -19,7 +19,7 @@ namespace Borepin.UWP
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
this.Suspending += _OnSuspending;
}
/// <summary>
@ -34,18 +34,16 @@ namespace Borepin.UWP
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
if (!(Window.Current.Content is Frame rootFrame))
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
rootFrame.NavigationFailed += _OnNavigationFailed;
Xamarin.Forms.Forms.Init(e);
@ -74,7 +72,7 @@ namespace Borepin.UWP
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
private void _OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
@ -86,9 +84,9 @@ namespace Borepin.UWP
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
private void _OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}

View File

@ -98,8 +98,8 @@
</Compile>
<Compile Include="PlatformInitializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\PreferenceService.cs" />
<Compile Include="Services\SecretService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorageService.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
@ -178,8 +178,8 @@
<PackageReference Include="Prism.DryIoc.Forms">
<Version>8.1.97</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2125" />
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.12" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2291" />
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.13" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.0" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
using Borepin.UWP.Services;
using Borepin.Service;
using Prism;
using Prism.Ioc;
using Borepin.Service.Storage;
namespace Borepin.UWP
{
@ -9,8 +9,8 @@ namespace Borepin.UWP
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IPreferenceService, PreferenceService>();
containerRegistry.Register<ISecretService, SecretService>();
containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>();
containerRegistry.Register<ISecretStorageService, SecretStorageService>();
}
}
}

View File

@ -1,9 +1,9 @@
using Borepin.Service;
using Borepin.Service.Storage;
using Xamarin.Essentials;
namespace Borepin.UWP.Services
{
public class PreferenceService : IPreferenceService
public class PreferenceStorageService : IPreferenceStorageService
{
public void Clear()
{

View File

@ -1,10 +1,10 @@
using Borepin.Service;
using Borepin.Service.Storage;
using System.Threading.Tasks;
using Xamarin.Essentials;
namespace Borepin.UWP.Services
{
public class SecretService : ISecretService
public class SecretStorageService : ISecretStorageService
{
public Task<string> GetAsync(string key)
{

View File

@ -19,6 +19,9 @@ namespace Borepin.iOS
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
ZXing.Net.Mobile.Forms.iOS.Platform.Init();
LoadApplication(new App(new PlatformInitializer()));
return base.FinishedLaunching(app, options);

View File

@ -29,9 +29,7 @@
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchSdkVersion>14.5</MtouchSdkVersion>
<CodesignProvision>Borepin Distribution Profile 2021</CodesignProvision>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
@ -52,14 +50,13 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchInterpreter>-all</MtouchInterpreter>
<MtouchExtraArgs>--optimize=experimental-xforms-product-type</MtouchExtraArgs>
<MtouchSdkVersion />
<CodesignProvision>Borepin Distribution Profile 2021</CodesignProvision>
<CodesignKey>iPhone Developer</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
@ -68,11 +65,10 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch>
<CodesignKey>iPhone Developer</CodesignKey>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Borepin Distribution Profile 2021</CodesignProvision>
<MtouchExtraArgs>--optimize=experimental-xforms-product-type</MtouchExtraArgs>
<MtouchLink>SdkOnly</MtouchLink>
<CodesignKey>iPhone Distribution</CodesignKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">
<AppExtensionDebugBundleId />
@ -80,8 +76,8 @@
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<Compile Include="Services\PreferenceService.cs" />
<Compile Include="Services\SecretService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorageService.cs" />
<None Include="Entitlements.plist" />
<None Include="Info.plist" />
<Compile Include="PlatformInitializer.cs" />
@ -185,7 +181,7 @@
</PackageReference>
<PackageReference Include="Xamarin.Essentials" Version="1.7.0" />
<PackageReference Include="Xamarin.Forms">
<Version>5.0.0.2125</Version>
<Version>5.0.0.2291</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
@ -198,8 +194,8 @@
<ItemGroup>
<Folder Include="Assets.xcassets\LaunchIcon.imageset\" />
</ItemGroup>
<Target Name="BeforeBuild" Condition=" '$(GITLAB_CI)' == 'true' ">
<Target Name="SetVersion">
<XmlPoke XmlInputPath="Info.plist" Query="//dict/key[. = 'CFBundleVersion']/following-sibling::string[1]" Value="$(CI_PIPELINE_ID)" />
<XmlPoke XmlInputPath="Info.plist" Query="//dict/key[. = 'CFBundleShortVersionString']/following-sibling::string[1]" Value="0.1.0" />
<XmlPoke XmlInputPath="Info.plist" Query="//dict/key[. = 'CFBundleShortVersionString']/following-sibling::string[1]" Value="$(CI_COMMIT_TAG.SubString(1))" />
</Target>
</Project>

View File

@ -35,12 +35,14 @@
<key>CFBundleShortVersionString</key>
<string>0.1</string>
<key>CFBundleVersion</key>
<string>0.2</string>
<string>1</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>NFCReaderUsageDescription</key>
<string>FabAccess needs to be able to read your card for authentication with the server.</string>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>NSCameraUsageDescription</key>
<string>Please allow access to the camera to scan barcodes</string>
</dict>
</plist>

View File

@ -9,7 +9,7 @@ namespace Borepin.iOS
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
}

View File

@ -1,5 +1,5 @@
using Borepin.iOS.Services;
using Borepin.Service;
using Borepin.Service.Storage;
using Prism;
using Prism.Ioc;
@ -9,8 +9,8 @@ namespace Borepin.iOS
{
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<IPreferenceService, PreferenceService>();
containerRegistry.Register<ISecretService, SecretService>();
containerRegistry.Register<IPreferenceStorageService, PreferenceStorageService>();
containerRegistry.Register<ISecretStorageService, SecretStorageService>();
}
}
}

View File

@ -1,9 +1,9 @@
using Borepin.Service;
using Borepin.Service.Storage;
using Xamarin.Essentials;
namespace Borepin.iOS.Services
{
public class PreferenceService : IPreferenceService
public class PreferenceStorageService : IPreferenceStorageService
{
public void Clear()
{

View File

@ -1,10 +1,10 @@
using Borepin.Service;
using Borepin.Service.Storage;
using System.Threading.Tasks;
using Xamarin.Essentials;
namespace Borepin.iOS.Services
{
public class SecretService : ISecretService
public class SecretStorageService : ISecretStorageService
{
public Task<string> GetAsync(string key)
{

View File

@ -8,13 +8,13 @@ namespace Borepin.macOS
[Register("AppDelegate")]
public class AppDelegate : FormsApplicationDelegate
{
readonly NSWindow window;
readonly NSWindow _Window;
public AppDelegate()
{
var style = NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Titled;
NSWindowStyle style = NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Titled;
var rect = new CoreGraphics.CGRect(200, 1000, 1024, 768);
window = new NSWindow(rect, style, NSBackingStore.Buffered, false)
CoreGraphics.CGRect rect = new CoreGraphics.CGRect(200, 1000, 1024, 768);
_Window = new NSWindow(rect, style, NSBackingStore.Buffered, false)
{
Title = "Xamarin.Forms on Mac!", // choose your own Title here
TitleVisibility = NSWindowTitleVisibility.Hidden
@ -23,7 +23,10 @@ namespace Borepin.macOS
public override NSWindow MainWindow
{
get { return window; }
get
{
return _Window;
}
}
public override void DidFinishLaunching(NSNotification notification)

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.props" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.props')" />
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -59,9 +59,6 @@
</XamMacArch>
</PropertyGroup>
<ItemGroup>
<Reference Include="DryIoc, Version=4.8.1.0, Culture=neutral, PublicKeyToken=dfbf2bd50fcf7768, processorArchitecture=MSIL">
<HintPath>..\..\packages\DryIoc.dll.4.8.1\lib\netstandard2.0\DryIoc.dll</HintPath>
</Reference>
<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>
</Reference>
@ -74,16 +71,16 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\Xamarin.Mac\Xamarin.Forms.Core.dll</HintPath>
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\Xamarin.Mac\Xamarin.Forms.Core.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\Xamarin.Mac\Xamarin.Forms.Platform.dll</HintPath>
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\Xamarin.Mac\Xamarin.Forms.Platform.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform.macOS, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\Xamarin.Mac\Xamarin.Forms.Platform.macOS.dll</HintPath>
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\Xamarin.Mac\Xamarin.Forms.Platform.macOS.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2125\lib\Xamarin.Mac\Xamarin.Forms.Xaml.dll</HintPath>
<HintPath>..\..\packages\Xamarin.Forms.5.0.0.2291\lib\Xamarin.Mac\Xamarin.Forms.Xaml.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Mac" />
</ItemGroup>
@ -131,10 +128,10 @@
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
<ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.props'))" />
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.targets'))" />
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.props'))" />
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets'))" />
</Target>
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2125\build\Xamarin.Forms.targets')" />
<Import Project="..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.5.0.0.2291\build\Xamarin.Forms.targets')" />
</Project>

View File

@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Prism" publicKeyToken="40ee6c3a2184dc59" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1909" newVersion="8.0.0.1909" />
<bindingRedirect oldVersion="0.0.0.0-8.1.97.5141" newVersion="8.1.97.5141" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DryIoc" publicKeyToken="dfbf2bd50fcf7768" culture="neutral" />

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DryIoc.dll" version="4.8.1" targetFramework="xamarinmac20" />
<package id="DryIoc.dll" version="4.8.4" 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.Forms" version="8.1.97" targetFramework="xamarinmac20" />
<package id="System.Reflection.Emit.Lightweight" version="4.7.0" targetFramework="xamarinmac20" />
<package id="Xamarin.Forms" version="5.0.0.2125" targetFramework="xamarinmac20" />
<package id="Xamarin.Forms" version="5.0.0.2291" targetFramework="xamarinmac20" />
</packages>

View File

@ -4,14 +4,13 @@ using Borepin.Page;
using Xamarin.Forms;
using Borepin.Dialog;
using Borepin.DialogModel;
using Borepin.Service.Connections;
using Borepin.Service.BFFH;
using Borepin.Service.Credentials;
using Prism;
using Borepin.Page.SetUpProcess;
using Borepin.PageModel.SetUpProcess;
using Borepin.Page.AddServerProcess;
using Borepin.PageModel.AddServerProcess;
using System;
namespace Borepin
{
@ -26,44 +25,40 @@ namespace Borepin
{
InitializeComponent();
Prism.Navigation.INavigationResult result = await NavigationService.NavigateAsync("/MainPage/NavigationPage/StartUpDistributorPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false);
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
#region Register Basic Navigation
containerRegistry.RegisterForNavigation<MainPage, MainPagePageModel>();
containerRegistry.RegisterForNavigation<MainPage, MainPageModel>();
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<StartUpDistributorPage, StartUpDistributorPageModel>();
containerRegistry.RegisterForNavigation<StartPage, StartPageModel>();
containerRegistry.RegisterForNavigation<MachinePage, MachinePageModel>();
containerRegistry.RegisterForNavigation<SettingsPage>();
containerRegistry.RegisterForNavigation<MachineListPage, MachineListPageModel>();
containerRegistry.RegisterForNavigation<ServerListPage, ServerListPageModel>();
containerRegistry.RegisterForNavigation<ServerPage, ServerPageModel>();
containerRegistry.RegisterForNavigation<ScannerPage>();
#endregion
#region Register Sequence Navigation
containerRegistry.RegisterForNavigation<WelcomePage, WelcomePageModel>("SetUpProcess_WelcomePage");
//containerRegistry.RegisterForNavigation<ScanPage, ScanPageModel>("SetUpProcess_ScanPage");
containerRegistry.RegisterForNavigation<LoginPasswordPage, LoginPasswordPageModel>("AddServerProcess_LoginPasswordPage");
containerRegistry.RegisterForNavigation<HostSelectPage, HostSelectPageModel>("AddServerProcess_HostSelectPage");
containerRegistry.RegisterForNavigation<LoginChoosePage, LoginChoosePageModel>("AddServerProcess_LoginChoosePage");
containerRegistry.RegisterForNavigation<AuthPlainPage, AuthPlainPageModel>("AddServerProcess_AuthPlainPage");
containerRegistry.RegisterForNavigation<SelectServerPage, SelectServerPageModel>("AddServerProcess_SelectServerPage");
containerRegistry.RegisterForNavigation<ChooseAuthTypePage, ChooseAuthTypePageModel>("AddServerProcess_ChooseAuthTypePage");
#endregion
#region Register Dialog
containerRegistry.RegisterDialog<ConfirmDialog, ConfirmDialogModel>();
containerRegistry.RegisterDialog<ScanDialog, ScanDialogModel>();
#endregion
#region Register Service
containerRegistry.Register<IConnectionService, ConnectionService>();
containerRegistry.Register<ICredentialService, CredentialService>();
containerRegistry.RegisterSingleton<IBFFHService, BFFHService>();
#endregion
}

View File

@ -0,0 +1,70 @@
using Borepin.Service.BFFH;
using Borepin.Service.BFFH.Exceptions;
using Prism.Navigation;
using Prism.Services;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Borepin.Base
{
/// <summary>
/// Base for all BFFH Based PageModels
/// </summary>
public abstract class ConnectionModelBase : PageModelBase
{
#region Private Fields
protected readonly IPageDialogService _PageDialogService;
protected readonly IBFFHService _BFFHService;
#endregion
#region Constructors
protected ConnectionModelBase(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bFFHService) : base(navigationService)
{
_PageDialogService = pageDialogService;
_BFFHService = bFFHService;
}
#endregion
#region Fields
/// <summary>
/// PageModel is Connected
/// </summary>
private bool _IsConnected = true;
public bool IsConnected
{
get => _IsConnected;
set => SetProperty(ref _IsConnected, value);
}
#endregion
#region Methods
/// <summary>
/// Checks connection to Server.
/// Display message if Connection is lost.
/// </summary>
/// <returns>True if connection is ok.</returns>
public async Task<bool> CheckConnection()
{
try
{
if(_BFFHService.CurrentConnection != null && !_BFFHService.IsConnected)
{
await _BFFHService.Reconnect().ConfigureAwait(false);
}
return true;
}
catch (ReconnectingFailedException)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Lost connection to server.", "Ok").ConfigureAwait(false);
});
IsConnected = false;
return false;
}
}
#endregion
}
}

View File

@ -5,22 +5,20 @@ using System.Threading.Tasks;
namespace Borepin.Base
{
/// <summary>
/// Base for all BFFH Based PageModels
/// Base for all MVVM Based PageModels
/// </summary>
public abstract class PageModelBase : BindableBase, INavigationAware
{
#region Private Properties
#region Private Fields
protected readonly INavigationService _NavigationService;
#endregion
#region Contructors
public PageModelBase(INavigationService navigationService)
protected PageModelBase(INavigationService navigationService)
{
_NavigationService = navigationService;
}
#endregion
#region Properties
#region Fields
/// <summary>
/// PageModel is Busy
/// </summary>
@ -41,8 +39,8 @@ namespace Borepin.Base
#endregion
#region INavigationAware
public abstract void OnNavigatedFrom(INavigationParameters parameters);
public abstract void OnNavigatedTo(INavigationParameters parameters);
public abstract void OnNavigatedFrom(INavigationParameters parameters);
#endregion
}
}

View File

@ -25,22 +25,42 @@
<None Remove="Behaviour\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="1.0.681">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Plugin.Multilingual" Version="1.0.2" />
<PackageReference Include="Prism.DryIoc.Forms" Version="8.1.97" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2125" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2291" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="ZXing.Net.MobileX.Forms" Version="3.0.1" />
</ItemGroup>
<ItemGroup>
<Compile Update="Page\AddServerProcess\ChooseAuthTypePage.xaml.cs">
<DependentUpon>ChooseAuthTypePage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\AddServerProcess\AuthPlainPage.xaml.cs">
<DependentUpon>AuthPlainPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\AddServerProcess\SelectServerPage.xaml.cs">
<DependentUpon>SelectServerPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\MachineListPage.xaml.cs">
<DependentUpon>MachineListPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\SettingsPage.xaml.cs">
<DependentUpon>SettingsPage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\SetUpProcess\WelcomePage.xaml.cs">
<DependentUpon>WelcomePage.xaml</DependentUpon>
</Compile>
<Compile Update="Page\StartPage.xaml.cs">
<DependentUpon>StartPage.xaml</DependentUpon>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@ -62,16 +82,16 @@
<EmbeddedResource Update="Dialog\ConfirmDialog.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\AddServerProcess\HostSelectPage.xaml">
<EmbeddedResource Update="Dialog\ScanDialog.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\ListPage.xaml">
<EmbeddedResource Update="Page\AddServerProcess\SelectServerPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\AddServerProcess\LoginChoosePage.xaml">
<EmbeddedResource Update="Page\AddServerProcess\ChooseAuthTypePage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\AddServerProcess\LoginPasswordPage.xaml">
<EmbeddedResource Update="Page\AddServerProcess\AuthPlainPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\MachinePage.xaml">
@ -80,6 +100,9 @@
<EmbeddedResource Update="Page\MainPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\ScannerPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\ServerListPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
@ -92,10 +115,7 @@
<EmbeddedResource Update="Page\SetUpProcess\WelcomePage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\StartUpDistributorPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Page\TestPage.xaml">
<EmbeddedResource Update="Page\StartPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Properties\Resources.resx">
@ -112,9 +132,6 @@
<EmbeddedResource Update="View\IsBusyView.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="View\ListItemView.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="View\ScanView.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>

View File

@ -13,7 +13,7 @@ namespace Borepin.Converter
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
throw new NotSupportedException();
}
}
}

View File

@ -19,7 +19,7 @@ namespace Borepin.Converter
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
throw new NotSupportedException();
}
}
}

View File

@ -29,7 +29,7 @@ namespace Borepin.Converter
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
throw new NotSupportedException();
}
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentView 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"
x:Class="Borepin.Dialog.ScanDialog">
<ContentView.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"/>
<Button Text="Abort" Command="{Binding AbortCommand}"/>
</StackLayout>
</ContentView.Content>
</ContentView>

View File

@ -7,12 +7,12 @@ using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Borepin.Page
namespace Borepin.Dialog
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage : ContentPage
public partial class ScanDialog : ContentView
{
public TestPage()
public ScanDialog()
{
InitializeComponent();
}

View File

@ -6,16 +6,31 @@ using System.Windows.Input;
namespace Borepin.DialogModel
{
/// <summary>
/// Confirm Dialog
/// </summary>
public class ConfirmDialogModel : BindableBase, IDialogAware
{
#region Private Fields
private object _Instance;
#endregion
#region Constructors
public ConfirmDialogModel()
{
ConfirmCommand = new DelegateCommand(ConfirmCommandExecute);
AbortCommand = new DelegateCommand(AbortCommandExecute);
}
#endregion
#region Fields
public event Action<IDialogParameters> RequestClose;
public bool CanCloseDialog()
{
return true;
}
#region Properties
private string _Title;
public string Title
{
@ -39,15 +54,13 @@ namespace Borepin.DialogModel
get => _ConfirmCommand;
set => SetProperty(ref _ConfirmCommand, value);
}
private void ConfirmCommandExecute()
public void ConfirmCommandExecute()
{
IDialogParameters parameters = new DialogParameters()
{
{ "result", "confirm" },
{ "instance", _Instance }
};
RequestClose(parameters);
}
@ -57,19 +70,18 @@ namespace Borepin.DialogModel
get => _AbortCommand;
set => SetProperty(ref _AbortCommand, value);
}
private void AbortCommandExecute()
public void AbortCommandExecute()
{
RequestClose(new DialogParameters { { "abort", true } });
IDialogParameters parameters = new DialogParameters()
{
{ "result", "abort" },
{ "instance", _Instance }
};
RequestClose(parameters);
}
#endregion
public event Action<IDialogParameters> RequestClose;
public bool CanCloseDialog()
{
return true;
}
#region IDialogAware
public void OnDialogClosed()
{
@ -81,5 +93,6 @@ namespace Borepin.DialogModel
Message = parameters.GetValue<string>("message");
_Instance = parameters.GetValue<object>("instance");
}
#endregion
}
}

View File

@ -0,0 +1,111 @@
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Windows.Input;
using ZXing;
namespace Borepin.DialogModel
{
public class ScanDialogModel : BindableBase, IDialogAware
{
#region Private Fields
private object _Instance;
#endregion
#region Constructors
public ScanDialogModel()
{
AbortCommand = new DelegateCommand(AbortCommandExecute);
ScannedCommand = new DelegateCommand(ScannedCommandExecute);
IsVisible = true;
IsScanning = true;
}
#endregion
#region Fields
public event Action<IDialogParameters> RequestClose;
public bool CanCloseDialog()
{
return true;
}
private Result _ScanResult;
public Result ScanResult
{
get => _ScanResult;
set => SetProperty(ref _ScanResult, value);
}
private bool _IsScanning;
public bool IsScanning
{
get => _IsScanning;
set => SetProperty(ref _IsScanning, value);
}
private bool _IsVisible;
public bool IsVisible
{
get => _IsVisible;
set => SetProperty(ref _IsVisible, value);
}
#endregion
#region Commands
private ICommand _ScannedCommand;
public ICommand ScannedCommand
{
get => _ScannedCommand;
set => SetProperty(ref _ScannedCommand, value);
}
public void ScannedCommandExecute()
{
IsScanning = false;
IsVisible = false;
IDialogParameters parameters = new DialogParameters()
{
{ "result", "scanned" },
{ "value", ScanResult.Text },
{ "instance", _Instance }
};
RequestClose(parameters);
}
private ICommand _AbortCommand;
public ICommand AbortCommand
{
get => _AbortCommand;
set => SetProperty(ref _AbortCommand, value);
}
public void AbortCommandExecute()
{
IsScanning = false;
IsVisible = false;
IDialogParameters parameters = new DialogParameters()
{
{ "result", "abort" },
{ "instance", _Instance }
};
RequestClose(parameters);
}
#endregion
#region IDialogAware
public void OnDialogClosed()
{
}
public void OnDialogOpened(IDialogParameters parameters)
{
_Instance = parameters.GetValue<object>("instance");
}
#endregion
}
}

View File

@ -10,20 +10,22 @@ namespace Borepin.Helpers
[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
const string ResourceId = "Borepin.Resources.Text.TextResource";
const string _ResourceId = "Borepin.Resources.Text.TextResource";
static readonly Lazy<ResourceManager> resmgr = new Lazy<ResourceManager>(() => new ResourceManager(ResourceId, typeof(TranslateExtension).GetTypeInfo().Assembly));
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 "";
}
var ci = CrossMultilingual.Current.CurrentCultureInfo;
System.Globalization.CultureInfo ci = CrossMultilingual.Current.CurrentCultureInfo;
var translation = resmgr.Value.GetString(Text, ci);
string translation = _Resmgr.Value.GetString(Text, ci);
if (translation == null)
{

View File

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

View File

@ -3,34 +3,61 @@ using System.Collections.Generic;
namespace Borepin.Model
{
public enum ConnectionTyp
{
SINGLE,
FEDERATED
}
public enum AuthenticationTyp
{
PLAIN
}
/// <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
public string Username { get; set; }
public ConnectionTyp ConnectionTyp { get; set; }
public AuthenticationTyp AuthenticationTyp { get; set; }
#region Methods
#region Equals and HashCode
public override bool Equals(object obj)
{
return obj is Connection connection &&
EqualityComparer<Uri>.Default.Equals(Address, connection.Address) &&
Username == connection.Username &&
string.Equals(Username, connection.Username, StringComparison.Ordinal) &&
ConnectionTyp == connection.ConnectionTyp &&
AuthenticationTyp == connection.AuthenticationTyp;
}
@ -40,10 +67,12 @@ namespace Borepin.Model
int hashCode = -904541792;
hashCode = hashCode * -1521134295 + EqualityComparer<Uri>.Default.GetHashCode(Address);
hashCode = hashCode * -1521134295 + LastTime.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Username);
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,8 @@
namespace Borepin.Model
{
public enum ConnectionTyp
{
SINGLE,
FEDERATED,
}
}

View File

@ -0,0 +1,19 @@
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,13 +0,0 @@
using System;
namespace Borepin.Model
{
public class HostCredentials
{
public Uri Host { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
}

View File

@ -6,7 +6,7 @@ namespace Borepin.Model
{
public class MachineVisualize : BindableBase
{
#region Private Properties
#region Private Fields
public readonly Machine _Machine;
#endregion
@ -20,7 +20,7 @@ namespace Borepin.Model
#endregion
#region Methods
public void LoadData()
public async void LoadData()
{
//ID = _Machine.Id;
//Space = new SpaceVisualize(_Machine.Space);
@ -28,6 +28,36 @@ namespace Borepin.Model
Description = _Machine.Description;
State = _Machine.State;
Manager = new UserVisualize(_Machine.Manager);
Manager.LoadData();
MachineInfoExtended machineInfoExtended = (await _Machine.Info.GetMachineInfoExtended().ConfigureAwait(false)).Item1;
if(machineInfoExtended != null)
{
if (machineInfoExtended.CurrentUser == null || machineInfoExtended.CurrentUser.Username == null)
{
CurrentUser = null;
}
else
{
CurrentUser = new UserVisualize(machineInfoExtended.CurrentUser);
CurrentUser.LoadData();
}
if (machineInfoExtended.TransferUser == null || machineInfoExtended.TransferUser.Username == null)
{
LastUser = null;
}
else
{
LastUser = new UserVisualize(machineInfoExtended.TransferUser);
LastUser.LoadData();
}
}
else
{
CurrentUser = null;
LastUser = null;
}
CanUse = !((UseInterface_Proxy)_Machine.Use).IsNull;
CanInUse = !((InUseInterface_Proxy) _Machine.Inuse).IsNull;
@ -38,7 +68,7 @@ namespace Borepin.Model
}
#endregion
#region Properties
#region Fields
private UUID _ID;
public UUID ID
{
@ -81,6 +111,20 @@ namespace Borepin.Model
set => SetProperty(ref _Manager, value);
}
private UserVisualize _CurrentUser;
public UserVisualize CurrentUser
{
get => _CurrentUser;
set => SetProperty(ref _CurrentUser, value);
}
private UserVisualize _LastUser;
public UserVisualize LastUser
{
get => _LastUser;
set => SetProperty(ref _LastUser, value);
}
private bool _CanUse;
public bool CanUse
{

View File

@ -5,7 +5,7 @@ namespace Borepin.Model
{
public class SpaceVisualize : BindableBase
{
#region Private Properties
#region Private Fields
public readonly Space _Space;
#endregion
@ -26,7 +26,7 @@ namespace Borepin.Model
}
#endregion
#region Properties
#region Fields
private UUID _ID;
public UUID ID
{

View File

@ -0,0 +1,76 @@
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

@ -0,0 +1,135 @@
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

@ -0,0 +1,22 @@
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

@ -5,7 +5,7 @@ namespace Borepin.Model
{
public class UserVisualize : BindableBase
{
#region Private Properties
#region Private Fields
public readonly User _User;
#endregion
@ -26,7 +26,7 @@ namespace Borepin.Model
}
#endregion
#region Properties
#region Fields
private UUID _ID;
public UUID ID
{

View File

@ -1,11 +1,9 @@
<?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.AddServerProcess.LoginPasswordPage"
xmlns:converters="clr-namespace:Borepin.Converter">
<NavigationPage.TitleView>
<Label Text="FabAccess" HorizontalOptions="End" Margin="0, 0, 10, 0" VerticalOptions="CenterAndExpand" FontSize="Medium" TextColor="{StaticResource FirstColor}"/>
</NavigationPage.TitleView>
x:Class="Borepin.Page.AddServerProcess.AuthPlainPage"
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Connect to Server">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>

View File

@ -5,9 +5,9 @@ using Xamarin.Forms.Xaml;
namespace Borepin.Page.AddServerProcess
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LoginChoosePage : ContentPage
public partial class AuthPlainPage : ContentPage
{
public LoginChoosePage()
public AuthPlainPage()
{
InitializeComponent();
}

View File

@ -1,11 +1,9 @@
<?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.AddServerProcess.LoginChoosePage"
xmlns:converters="clr-namespace:Borepin.Converter">
<NavigationPage.TitleView>
<Label Text="FabAccess" HorizontalOptions="End" Margin="0, 0, 10, 0" VerticalOptions="CenterAndExpand" FontSize="Medium" TextColor="{StaticResource FirstColor}"/>
</NavigationPage.TitleView>
x:Class="Borepin.Page.AddServerProcess.ChooseAuthTypePage"
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Connect to Server">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
@ -18,7 +16,7 @@
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Sign In:" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Button Text="Login with Password" Command="{Binding LoginPasswordCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="Login with Password" Command="{Binding AuthPlainCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Label Text="or" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Button Text="Login with Card" Style="{StaticResource Style_Button_Primary}" IsEnabled="False"/>

View File

@ -5,9 +5,9 @@ using Xamarin.Forms.Xaml;
namespace Borepin.Page.AddServerProcess
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LoginPasswordPage : ContentPage
public partial class ChooseAuthTypePage : ContentPage
{
public LoginPasswordPage()
public ChooseAuthTypePage()
{
InitializeComponent();
}

View File

@ -1,11 +1,9 @@
<?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.AddServerProcess.HostSelectPage"
xmlns:converters="clr-namespace:Borepin.Converter">
<NavigationPage.TitleView>
<Label Text="FabAccess" HorizontalOptions="End" Margin="0, 0, 10, 0" VerticalOptions="CenterAndExpand" FontSize="Medium" TextColor="{StaticResource FirstColor}"/>
</NavigationPage.TitleView>
x:Class="Borepin.Page.AddServerProcess.SelectServerPage"
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Connect to Server">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
@ -18,9 +16,15 @@
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Host" Style="{StaticResource Style_Label_Property_Title}"></Label>
<Entry Text="{Binding Host}"/>
<Button Text="Demo Host Address" Command="{Binding DetectHostCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="Select Host" Command="{Binding UseHostCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Entry Text="{Binding Server}"/>
<Button Text="Connect to Server" Command="{Binding ConnectToServerCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button Text="Scan QR-Code" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}">
<Button.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean"
iOS="false"
Android="true"/>
</Button.IsVisible>
</Button>
</StackLayout>
</StackLayout>
</ContentPage.Content>

View File

@ -4,9 +4,9 @@ using Xamarin.Forms.Xaml;
namespace Borepin.Page.AddServerProcess
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HostSelectPage : ContentPage
public partial class SelectServerPage : ContentPage
{
public HostSelectPage()
public SelectServerPage()
{
InitializeComponent();
}

View File

@ -1,19 +0,0 @@
<?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.ListPage">
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding ListItemViewModel_List}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<views:ListItemView />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<?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.MachineListPage"
xmlns:converters="clr-namespace:Borepin.Converter">
<NavigationPage.TitleView>
<Label Text="Machines" HorizontalOptions="End" Margin="0, 0, 10, 0" VerticalOptions="CenterAndExpand" FontSize="Medium" TextColor="{StaticResource FirstColor}"/>
</NavigationPage.TitleView>
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Machines">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
@ -18,7 +16,15 @@
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<ListView ItemsSource="{Binding MachineListItemViewModel_List}" IsVisible="{Binding IsConnected}">
<Button Text="Scan QR-Code" Command="{Binding ScanCodeCommand}" Style="{StaticResource Style_Button_Primary}">
<Button.IsVisible>
<OnPlatform x:TypeArguments="x:Boolean"
iOS="false"
Android="true"/>
</Button.IsVisible>
</Button>
<RefreshView Command="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing}">
<ListView ItemsSource="{Binding MachineListItemViewModel_List}" IsVisible="{Binding IsConnected}" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
@ -27,8 +33,9 @@
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Label Text="Please connect to Server" IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"></Label>
</RefreshView>
</StackLayout>
<Label Text="Please connect to Server" IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"></Label>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -2,7 +2,8 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.MachinePage"
xmlns:converters="clr-namespace:Borepin.Converter">
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Machine">
<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}}"/>
</NavigationPage.TitleView>
@ -20,19 +21,30 @@
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<StackLayout IsVisible="{Binding IsConnected}">
<Label Text="{Binding MachineItem.Name}" Style="{StaticResource LabelStyle_Title}"/>
<Label Text="{Binding MachineItem.Description}" Style="{StaticResource Style_Label_Text}"/>
<Label Text="{Binding MachineItem.Description}" Style="{StaticResource Style_Label_Text_Center}"/>
<StackLayout IsVisible="{Binding MachineItem.CanUse}">
<Button Text="Use" Command="{Binding UseMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CanInUse}">
<Button Text="GiveBack" Command="{Binding GiveBackMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CurrentUser, Converter={StaticResource IsNotNullBoolConverter}}">
<Label Text="Current User:" Style="{StaticResource Style_Label_Property_Title}"/>
<Label Text="{Binding MachineItem.CurrentUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/>
</StackLayout>
<StackLayout IsVisible="{Binding MachineItem.LastUser, Converter={StaticResource IsNotNullBoolConverter}}">
<Label Text="Last User:" Style="{StaticResource Style_Label_Property_Title}"/>
<Label Text="{Binding MachineItem.LastUser.Username}" Style="{StaticResource Style_Label_Property_Text}"/>
</StackLayout>
<StackLayout IsVisible="{Binding MachineItem.CanManage}">
<Label Text="Manage Machine:" Style="{StaticResource Style_Label_Property_Title}"/>
<Button Text="Force Free" Command="{Binding ForceFreeMachineCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
</StackLayout>
<Label Text="Please connect to Server" IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}"></Label>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -2,13 +2,12 @@
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.MainPage"
x:Name="page">
Title="MainPage">
<FlyoutPage.Flyout>
<ContentPage Title="FabAccess">
<StackLayout Margin="0,50,0,0">
<Button Text="Machines" Command="{Binding NavigateCommand}" CommandParameter="MachineListPage" />
<Button Text="Servers" Command="{Binding NavigateCommand}" CommandParameter="ServerListPage" />
<!--<Button Text="Settings" Command="{Binding NavigateCommand}" CommandParameter="SettingsPage" />-->
</StackLayout>
</ContentPage>
</FlyoutPage.Flyout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<zxing:ZXingScannerPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.ScannerPage"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
Title="Full screen"
OnScanResult="Handle_OnScanResult"
IsScanning="true">
</zxing:ZXingScannerPage>

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using ZXing;
using ZXing.Net.Mobile.Forms;
namespace Borepin.Page
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ScannerPage : ZXingScannerPage
{
public ScannerPage()
{
InitializeComponent();
}
public void Handle_OnScanResult(Result result)
{
Device.BeginInvokeOnMainThread(async () =>
{
await DisplayAlert("Scanned result", result.Text, "OK").ConfigureAwait(false);
});
}
protected override void OnAppearing()
{
base.OnAppearing();
IsScanning = true;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
IsScanning = false;
}
}
}

View File

@ -3,10 +3,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Borepin.View"
x:Class="Borepin.Page.ServerListPage"
xmlns:converters="clr-namespace:Borepin.Converter">
<NavigationPage.TitleView>
<Label Text="Servers" HorizontalOptions="End" Margin="0, 0, 10, 0" VerticalOptions="CenterAndExpand" FontSize="Medium" TextColor="{StaticResource FirstColor}"/>
</NavigationPage.TitleView>
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Servers">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
@ -19,7 +17,7 @@
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="Active Connection" IsVisible="{Binding HasActiveConnection}"/>
<ListView ItemsSource="{Binding ActiveConnection}" IsVisible="{Binding HasActiveConnection}">
<ListView ItemsSource="{Binding ActiveConnection}" IsVisible="{Binding HasActiveConnection}" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
@ -29,7 +27,7 @@
</ListView.ItemTemplate>
</ListView>
<Label Text="Last Connections"/>
<ListView ItemsSource="{Binding ServerListItemViewModel_List}">
<ListView ItemsSource="{Binding ServerListItemViewModel_List}" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
@ -38,7 +36,7 @@
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="Connect to new Server" Command="{Binding AddInstancesCommand}"/>
<Button Text="Connect to new Server" Command="{Binding AddInstancesCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>

View File

@ -2,7 +2,8 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.ServerPage"
xmlns:converters="clr-namespace:Borepin.Converter">
xmlns:converters="clr-namespace:Borepin.Converter"
Title="Server">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
@ -15,9 +16,9 @@
</StackLayout>
<StackLayout IsVisible="{Binding IsBusy, Converter={StaticResource InvertBoolConverter}}">
<Label Text="{Binding Connection_Item.Address}"/>
<Button IsVisible="{Binding IsConnected, Converter={StaticResource InvertBoolConverter}}" Text="Connect" Command="{Binding ConnectCommand}"/>
<Button IsVisible="{Binding IsConnected}" Text="Disconnect" Command="{Binding ConnectCommand}"/>
<Button Text="Delete" Command="{Binding DeleteCommand}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection, Converter={StaticResource InvertBoolConverter}}" Text="Connect" Command="{Binding ConnectCommand}" Style="{StaticResource Style_Button_Primary}"/>
<Button IsVisible="{Binding InstanceIsActiveConnection}" Text="Disconnect" Command="{Binding DisconnectCommand}" Style="{StaticResource Style_Button_Admin}"/>
<Button Text="Delete" Command="{Binding DeleteCommand}" Style="{StaticResource Style_Button_Admin}"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>

View File

@ -3,12 +3,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Borepin.Page.SetUpProcess.ScanPage"
xmlns:i18n="clr-namespace:Borepin.Helpers"
xmlns:views="clr-namespace:Borepin.View">
xmlns:views="clr-namespace:Borepin.View"
Title="FabAccess">
<ContentPage.Content>
<ScrollView>
<StackLayout Style="{StaticResource Style_StackLayout_Content}">
<views:ScanView />
<Label Text="{i18n:Translate SetUp_ScanPage_Text}" Style="{StaticResource Style_Label_Text}"/>
<Label Text="{i18n:Translate SetUp_ScanPage_Text}" Style="{StaticResource Style_Label_Text_Center}"/>
<Button Text="{i18n:Translate SetUp_ScanPage_Button}" Command="{Binding NextCommand}" Style="{StaticResource Style_Button_Primary}"/>
</StackLayout>
</ScrollView>

View File

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

View File

@ -0,0 +1,11 @@
<?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.StartPage"
Title="Start">
<ContentPage.Content>
<StackLayout Padding="20">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -1,13 +1,12 @@

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

View File

@ -1,19 +0,0 @@
<?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.StartUpDistributorPage"
xmlns:converters="clr-namespace:Borepin.Converter">
<ContentPage.Resources>
<ResourceDictionary>
<converters:InvertBoolConverter x:Key="InvertBoolConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="20">
<StackLayout IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}"></ActivityIndicator>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -1,20 +0,0 @@
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 StartUpDistributorPage : ContentPage
{
public StartUpDistributorPage()
{
InitializeComponent();
}
}
}

View File

@ -1,21 +0,0 @@
<?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.TestPage"
xmlns:converters="clr-namespace:Borepin.Converter">
<ContentPage.Resources>
<ResourceDictionary>
<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}}">
<Label Text="TestPage"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View File

@ -1,48 +1,46 @@
using Borepin.Base;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Borepin.Base;
using Borepin.Model;
using Borepin.Service.BFFH;
using Borepin.Service.Connections;
using Borepin.Service.BFFH.Exceptions;
using Prism.Commands;
using Prism.Navigation;
using Prism.Services;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Borepin.PageModel.AddServerProcess
{
public class LoginPasswordPageModel : PageModelBase
public class AuthPlainPageModel : PageModelBase
{
#region Private Properties
#region Private Fields
private readonly IBFFHService _BFFHService;
private readonly IConnectionService _ConnectionService;
private readonly IPageDialogService _PageDialogService;
private Connection _Connection;
#endregion
#region Constructors
public LoginPasswordPageModel(INavigationService navigationService, IBFFHService bffhService, IConnectionService connectionService, IPageDialogService pageDialogService) : base(navigationService)
public AuthPlainPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService)
{
_BFFHService = bffhService;
_ConnectionService = connectionService;
_PageDialogService = pageDialogService;
AuthenticateCommand = new DelegateCommand(async () => await AuthenticateCommandExecuted());
Task.Run(LoadData);
AuthenticateCommand = new DelegateCommand(async () => await AuthenticateCommandExecute().ConfigureAwait(false));
}
#endregion
#region LoadData
public override Task LoadData()
{
IsBusy = false;
Username = _Connection.Username;
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region Properties
#region Fields
private string _Username;
public string Username
{
@ -65,52 +63,61 @@ namespace Borepin.PageModel.AddServerProcess
get => _AuthenticateCommand;
set => SetProperty(ref _AuthenticateCommand, value);
}
private async Task AuthenticateCommandExecuted()
public async Task AuthenticateCommandExecute()
{
IsBusy = true;
Connection connection_update = _BFFHService.ActiveConnection;
_Connection.Username = Username;
connection_update.Username = Username;
if(!await _BFFHService.Authenticate(connection_update, Password))
if (_BFFHService.IsConnected)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok");
await _BFFHService.Disconnect().ConfigureAwait(true);
}
try
{
await _BFFHService.Connect(_Connection, Password).ConfigureAwait(true);
}
catch (ConnectingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
return;
}
catch (AuthenticatingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
return;
}
try
{
await _ConnectionService.AddConnection(_BFFHService.ActiveConnection);
}
catch (ArgumentException)
{
// Could be better catched
}
await _ConnectionService.LogConnect(_BFFHService.ActiveConnection);
var result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
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
}

View File

@ -0,0 +1,76 @@
using Borepin.Base;
using Borepin.Model;
using Prism.Navigation;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess
{
public class ChooseAuthTypePageModel : PageModelBase
{
#region Private Fields
private Connection _Connection;
#endregion
#region Contructors
public ChooseAuthTypePageModel(INavigationService navigationService) : base(navigationService)
{
AuthPlainCommand = new Command(AuthPlainCommandExecute);
}
#endregion
#region LoadData
public override Task LoadData()
{
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region Commands
private ICommand _AuthPlainCommand;
public ICommand AuthPlainCommand
{
get => _AuthPlainCommand;
set => SetProperty(ref _AuthPlainCommand, value);
}
public async void AuthPlainCommandExecute()
{
_Connection.AuthenticationTyp = AuthenticationTyp.PLAIN;
INavigationParameters parameters = new NavigationParameters()
{
{"instance", _Connection },
};
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
}
}

View File

@ -1,131 +0,0 @@
using Borepin.Base;
using Borepin.Service.BFFH;
using Prism.Navigation;
using Prism.Services;
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess
{
public class HostSelectPageModel : PageModelBase
{
#region Private Properties
private readonly IBFFHService _BFFHService;
private readonly IPageDialogService _PageDialogService;
#endregion
#region Constructors
public HostSelectPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService)
{
_BFFHService = bffhService;
_PageDialogService = pageDialogService;
UseHostCommand = new Command(UseHostCommandExecuted);
DetectHostCommand = new Command(DetectHostCommandExecuted);
Task.Run(LoadData);
}
#endregion
#region LoadData
public override Task LoadData()
{
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region Properties
private string _Host;
public string Host
{
get => _Host;
set => SetProperty(ref _Host, value);
}
private ObservableCollection<string> _KnownHost_List;
public ObservableCollection<string> KnownHost_List
{
get => _KnownHost_List;
set => SetProperty(ref _KnownHost_List, value);
}
#endregion
#region Commands
private ICommand _UseHostCommand;
public ICommand UseHostCommand
{
get => _UseHostCommand;
set => SetProperty(ref _UseHostCommand, value);
}
private async void UseHostCommandExecuted()
{
IsBusy = true;
UriBuilder builder = new UriBuilder(Host);
if(builder.Port == 80)
{
builder.Port = 59661;
}
Model.Connection connection = new Model.Connection()
{
Address = builder.Uri
};
if(_BFFHService.ActiveConnection != null)
{
await _BFFHService.Disconnect();
}
try
{
await _BFFHService.Connect(connection);
}
catch (Capnp.Rpc.RpcException exception) when (exception.Message == "TcpRpcClient is unable to connect")
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok");
IsBusy = false;
return;
}
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_LoginChoosePage");
if(!result.Success)
{
System.Diagnostics.Debugger.Break();
}
}
private ICommand _DetectHostCommand;
public ICommand DetectHostCommand
{
get => _DetectHostCommand;
set => SetProperty(ref _DetectHostCommand, value);
}
private void DetectHostCommandExecuted()
{
// Use Demo Host
Host = "127.0.0.1:59661";
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
}
}

View File

@ -1,57 +0,0 @@
using Borepin.Base;
using Prism.Navigation;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess
{
public class LoginChoosePageModel : PageModelBase
{
#region Contructors
public LoginChoosePageModel(INavigationService navigationService) : base(navigationService)
{
LoginPasswordCommand = new Command(LoginPasswordCommandExecuted);
}
#endregion
#region LoadData
public override Task LoadData()
{
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region Commands
private ICommand _LoginPasswordCommand;
public ICommand LoginPasswordCommand
{
get => _LoginPasswordCommand;
set => SetProperty(ref _LoginPasswordCommand, value);
}
private async void LoginPasswordCommandExecuted()
{
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_LoginPasswordPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
IsBusy = false;
}
#endregion
}
}

View File

@ -0,0 +1,181 @@
using Borepin.Base;
using Borepin.Model;
using Borepin.Service.BFFH;
using Prism.AppModel;
using Prism.Navigation;
using Prism.Services;
using Prism.Services.Dialogs;
using System;
using System.Globalization;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess
{
public class SelectServerPageModel : PageModelBase, IPageLifecycleAware
{
#region Private Fields
private readonly IBFFHService _BFFHService;
private readonly IPageDialogService _PageDialogService;
private readonly IDialogService _DialogService;
private Connection _Connection;
private bool _Scanned;
#endregion
#region Constructors
public SelectServerPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService, IDialogService dialogService) : base(navigationService)
{
_BFFHService = bffhService;
_PageDialogService = pageDialogService;
_DialogService = dialogService;
ConnectToServerCommand = new Command(async ()=> await ConnectToServerExecute().ConfigureAwait(false));
DetectLocalServerCommand = new Command(DetectHostCommandExecute);
ScanCodeCommand = new Command(ScanCodeCommandExecute);
}
#endregion
#region LoadData
public override Task LoadData()
{
Server = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", _Connection.Address.Host, _Connection.Address.Port);
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region Fields
private string _Server;
public string Server
{
get => _Server;
set => SetProperty(ref _Server, value);
}
#endregion
#region Commands
private ICommand _ConnectToServerCommand;
public ICommand ConnectToServerCommand
{
get => _ConnectToServerCommand;
set => SetProperty(ref _ConnectToServerCommand, value);
}
public async Task ConnectToServerExecute()
{
IsBusy = true;
try
{
UriBuilder builder = new UriBuilder(Server);
if (builder.Port == 80)
{
builder.Port = 59661;
}
_Connection = new Connection()
{
Address = builder.Uri,
};
}
catch (UriFormatException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Server address is invaild.", "Ok").ConfigureAwait(false);
IsBusy = false;
return;
}
if (!await _BFFHService.TestConnection(_Connection).ConfigureAwait(true))
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
return;
}
INavigationParameters parameters = new NavigationParameters()
{
{"instance", _Connection },
};
await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage", parameters).ConfigureAwait(false);
}
private ICommand _ScanCodeCommand;
public ICommand ScanCodeCommand
{
get => _ScanCodeCommand;
set => SetProperty(ref _ScanCodeCommand, value);
}
public void ScanCodeCommandExecute()
{
_DialogService.ShowDialog("ScanDialog", ScanCodeCommandExecute_Dialog);
}
public void ScanCodeCommandExecute_Dialog(IDialogResult result)
{
if (string.Equals(result.Parameters.GetValue<string>("result"), "scanned", StringComparison.Ordinal))
{
Server = result.Parameters["value"] as string;
_Scanned = true;
}
}
private ICommand _DetectLocalServerCommand;
public ICommand DetectLocalServerCommand
{
get => _DetectLocalServerCommand;
set => SetProperty(ref _DetectLocalServerCommand, value);
}
public void DetectHostCommandExecute()
{
// Get Example Server Address
Server = "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();
}
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
#endregion
}
}

View File

@ -1,57 +0,0 @@
using Borepin.Model;
using Borepin.ViewModel;
using Prism.Mvvm;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel
{
public class ListPageModel : BindableBase
{
public ListPageModel()
{
ListItemViewModel_List = new List<ListItemViewModel>()
{
new ListItemViewModel(
new ListItem()
{
Value1 = "ListItem 1"
}),
new ListItemViewModel(
new ListItem()
{
Value1 = "ListItem 2"
}),
new ListItemViewModel(
new ListItem()
{
Value1 = "ListItem 3"
}),
};
SelectListItemCommand = new Command<object>(SelectListItemCommandExecuted);
}
private List<ListItemViewModel> _ListItemViewModel_List;
public List<ListItemViewModel> ListItemViewModel_List
{
get => _ListItemViewModel_List;
set => SetProperty(ref _ListItemViewModel_List, value);
}
private ICommand _SelectListItemCommand;
public ICommand SelectListItemCommand
{
get => _SelectListItemCommand;
set => SetProperty(ref _SelectListItemCommand, value);
}
private void SelectListItemCommandExecuted(object obj)
{
System.Diagnostics.Debugger.Break();
}
}
}

View File

@ -7,41 +7,49 @@ using Prism.Navigation;
using Borepin.Service.BFFH;
using Borepin.Base;
using FabAccessAPI.Schema;
using Prism.Services.Dialogs;
using Prism.Services;
using Prism.AppModel;
namespace Borepin.PageModel
{
public class MachineListPageModel : PageModelBase
public class MachineListPageModel : ConnectionModelBase, IPageLifecycleAware
{
#region Private Properties
private readonly IBFFHService _BFFHService;
#region Private Fields
private readonly IDialogService _DialogService;
private Machine _NextMachine;
#endregion
#region Constructors
public MachineListPageModel(INavigationService navigationService, IBFFHService bFFHService) : base(navigationService)
public MachineListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bFFHService, IDialogService dialogService) : base(navigationService, pageDialogService, bFFHService)
{
_BFFHService = bFFHService;
_DialogService = dialogService;
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecuted);
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute);
ScanCodeCommand = new DelegateCommand(ScanCodeCommandExecute);
RefreshCommand = new DelegateCommand(async ()=> await RefreshCommandExecute().ConfigureAwait(true));
}
#endregion
#region Data
public override async Task LoadData()
{
if (_BFFHService.ActiveConnection == null)
if (! await CheckConnection().ConfigureAwait(false))
{
IsConnected = false;
IsBusy = false;
return;
}
else
{
IsConnected = true;
}
IMachineSystem machineInterface = await _BFFHService.GetMachineSystemInterface();
MachineSystem.IInfoInterface infoInterface = await machineInterface.Info();
IMachineSystem machineInterface = await _BFFHService.GetMachineSystemInterface().ConfigureAwait(false);
IReadOnlyList<Machine> machine_list = await infoInterface.GetMachineList();
MachineSystem.IInfoInterface infoInterface = await machineInterface.Info().ConfigureAwait(false);
IReadOnlyList<Machine> machine_list = await infoInterface.GetMachineList().ConfigureAwait(false);
List<MachineListItemViewModel> viewmodel_list = new List<MachineListItemViewModel>();
foreach (Machine machine in machine_list)
@ -55,43 +63,113 @@ namespace Borepin.PageModel
}
#endregion
#region Properties
private bool _IsConnected = false;
public bool IsConnected
{
get => _IsConnected;
set => SetProperty(ref _IsConnected, value);
}
private List<MachineListItemViewModel> _MachineListItemViewModel_List;
public List<MachineListItemViewModel> MachineListItemViewModel_List
#region Fields
private IList<MachineListItemViewModel> _MachineListItemViewModel_List;
public IList<MachineListItemViewModel> MachineListItemViewModel_List
{
get => _MachineListItemViewModel_List;
set => SetProperty(ref _MachineListItemViewModel_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()
{
await LoadData().ConfigureAwait(true);
IsRefreshing = false;
}
private ICommand _SelectInstanceCommand;
public ICommand SelectInstanceCommand
{
get => _SelectInstanceCommand;
set => SetProperty(ref _SelectInstanceCommand, value);
}
private async void SelectInstanceCommandExecuted(object obj)
public async void SelectInstanceCommandExecute(object obj)
{
MachineListItemViewModel viewmodel = obj as MachineListItemViewModel;
NavigationParameters parameters = new NavigationParameters
{
{ "name", viewmodel.Instance.Name }
{ "id", viewmodel.Instance.Id },
};
INavigationResult result = await _NavigationService.NavigateAsync($"MachinePage", parameters);
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
await _NavigationService.NavigateAsync($"MachinePage", parameters).ConfigureAwait(false);
}
private ICommand _ScanCodeCommand;
public ICommand ScanCodeCommand
{
get => _ScanCodeCommand;
set => SetProperty(ref _ScanCodeCommand, value);
}
public void ScanCodeCommandExecute()
{
IsBusy = true;
_DialogService.ShowDialog("ScanDialog", ScanCodeCommandExecute_Dialog);
}
public async void ScanCodeCommandExecute_Dialog(IDialogResult result)
{
if (string.Equals(result.Parameters.GetValue<string>("result"), "scanned", System.StringComparison.Ordinal))
{
if (! _BFFHService.IsConnected)
{
IsConnected = false;
IsBusy = false;
return;
}
IMachineSystem machineInterface = await _BFFHService.GetMachineSystemInterface().ConfigureAwait(false);
MachineSystem.IInfoInterface infoInterface = await machineInterface.Info().ConfigureAwait(false);
Machine machine = (await infoInterface.GetMachineURN(result.Parameters.GetValue<string>("value")).ConfigureAwait(false)).Item1;
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
@ -101,10 +179,9 @@ namespace Borepin.PageModel
}
public override void OnNavigatedTo(INavigationParameters parameters)
public override async void OnNavigatedTo(INavigationParameters parameters)
{
IsBusy = true;
Task.Run(LoadData);
await LoadData().ConfigureAwait(false);
}
#endregion
}

View File

@ -7,25 +7,24 @@ using FabAccessAPI.Schema;
using Borepin.Service.BFFH;
using static FabAccessAPI.Schema.MachineSystem;
using Borepin.Model;
using Prism.Services;
using Borepin.Service.BFFH.Exceptions;
namespace Borepin.PageModel
{
public class MachinePageModel : PageModelBase
public class MachinePageModel : ConnectionModelBase
{
#region Private Properties
private readonly IBFFHService _BFFHService;
private string _Name;
#region Private Fields
private string _ID;
private Machine _Machine;
#endregion
#region Contructors
public MachinePageModel(INavigationService navigationService, IBFFHService bffhService) : base(navigationService)
public MachinePageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bffhService) : base(navigationService, pageDialogService, bffhService)
{
_BFFHService = bffhService;
UseMachineCommand = new DelegateCommand(UseMachineCommandExecuted);
GiveBackMachineCommand = new DelegateCommand(GiveBackMachineCommandExecuted);
ForceFreeMachineCommand = new DelegateCommand(ForceFreeMachineCommandExecuted);
UseMachineCommand = new DelegateCommand(UseMachineCommandExecute);
GiveBackMachineCommand = new DelegateCommand(GiveBackMachineCommandExecute);
ForceFreeMachineCommand = new DelegateCommand(ForceFreeMachineCommandExecute);
}
#endregion
@ -33,12 +32,29 @@ namespace Borepin.PageModel
public override async Task LoadData()
{
IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
{
IsConnected = false;
IMachineSystem machineSystem = await _BFFHService.GetMachineSystemInterface();
IsBusy = false;
return;
}
IInfoInterface info = await machineSystem.Info();
IMachineSystem machineSystem;
try
{
machineSystem = await _BFFHService.GetMachineSystemInterface().ConfigureAwait(false);
}
catch(ReconnectingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Lost connection to server.", "Ok").ConfigureAwait(false);
_Machine = (await info.GetMachine(_Name)).Item1;
return;
}
IInfoInterface info = await machineSystem.Info().ConfigureAwait(false);
_Machine = (await info.GetMachine(_ID).ConfigureAwait(false)).Item1;
MachineItem = new MachineVisualize(_Machine);
MachineItem.LoadData();
@ -46,7 +62,7 @@ namespace Borepin.PageModel
}
#endregion
#region Properties
#region Fields
private MachineVisualize _MachineItem;
public MachineVisualize MachineItem
{
@ -64,12 +80,23 @@ namespace Borepin.PageModel
set => SetProperty(ref _UseMachineCommand, value);
}
private async void UseMachineCommandExecuted()
public async void UseMachineCommandExecute()
{
IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
{
IsConnected = false;
IsBusy = false;
return;
}
Machine.IUseInterface useInterface = _Machine.Use;
await useInterface.Use();
await LoadData();
await useInterface.Use().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
IsBusy = false;
}
private ICommand _GiveBackMachineCommand;
@ -79,12 +106,23 @@ namespace Borepin.PageModel
set => SetProperty(ref _GiveBackMachineCommand, value);
}
private async void GiveBackMachineCommandExecuted()
public async void GiveBackMachineCommandExecute()
{
IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
{
IsConnected = false;
IsBusy = false;
return;
}
Machine.IInUseInterface inUseInterface = _Machine.Inuse;
await inUseInterface.GiveBack();
await LoadData();
await inUseInterface.GiveBack().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
IsBusy = false;
}
private ICommand _ForceFreeMachineCommand;
@ -94,12 +132,23 @@ namespace Borepin.PageModel
set => SetProperty(ref _ForceFreeMachineCommand, value);
}
private async void ForceFreeMachineCommandExecuted()
public async void ForceFreeMachineCommandExecute()
{
IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
{
IsConnected = false;
IsBusy = false;
return;
}
Machine.IManageInterface manageInterface = _Machine.Manage;
await manageInterface.ForceFree();
await LoadData();
await manageInterface.ForceFree().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
IsBusy = false;
}
#endregion
@ -109,12 +158,11 @@ namespace Borepin.PageModel
}
public override void OnNavigatedTo(INavigationParameters parameters)
public override async void OnNavigatedTo(INavigationParameters parameters)
{
_Name = parameters["name"] as string;
_ID = parameters["id"] as string;
IsBusy = true;
Task.Run(LoadData);
await LoadData().ConfigureAwait(false);
}
#endregion
}

View File

@ -0,0 +1,51 @@
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Borepin.Base;
using Prism.Navigation;
using Xamarin.Forms;
namespace Borepin.PageModel
{
public class MainPageModel : PageModelBase
{
#region Constructors
public MainPageModel(INavigationService navigationService) : base(navigationService)
{
NavigateCommand = new Command<string>(NavigateCommandExecute);
}
#endregion
#region LoadData
public override Task LoadData()
{
return Task.CompletedTask;
}
#endregion
#region Commands
private ICommand _NavigationCommand;
public ICommand NavigateCommand
{
get => _NavigationCommand;
set => SetProperty(ref _NavigationCommand, value);
}
public async void NavigateCommandExecute(string view)
{
await _NavigationService.NavigateAsync($"NavigationPage/{ view }").ConfigureAwait(false);
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
}
}

View File

@ -1,35 +0,0 @@
using Prism.Mvvm;
using Prism.Navigation;
using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel
{
public class MainPagePageModel : BindableBase
{
private INavigationService _NavigationService;
public MainPagePageModel(INavigationService navigationService)
{
_NavigationService = navigationService;
NavigateCommand = new Command<string>(NavigateCommandExecuted);
}
private ICommand _NavigationCommand;
public ICommand NavigateCommand
{
get => _NavigationCommand;
set => SetProperty(ref _NavigationCommand, value);
}
private async void NavigateCommandExecuted(string view)
{
var result = await _NavigationService.NavigateAsync($"NavigationPage/{view}");
if(!result.Success)
{
System.Diagnostics.Debugger.Break();
}
}
}
}

View File

@ -1,5 +1,4 @@
using Borepin.ViewModel;
using Prism.Mvvm;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
@ -7,42 +6,40 @@ using Borepin.Model;
using System.Windows.Input;
using Prism.Commands;
using Prism.Navigation;
using Borepin.Service.Connections;
using Borepin.Service.BFFH;
using Borepin.Base;
using System;
namespace Borepin.PageModel
{
public class ServerListPageModel : PageModelBase
{
#region Private Properties
private readonly IConnectionService _ConnectionService;
#region Private Fields
private readonly IBFFHService _BFFHService;
#endregion
#region Constructors
public ServerListPageModel(INavigationService navigationService, IConnectionService connectionService, IBFFHService bffhService) : base(navigationService)
public ServerListPageModel(INavigationService navigationService, IBFFHService bffhService) : base(navigationService)
{
_ConnectionService = connectionService;
_BFFHService = bffhService;
AddInstancesCommand = new DelegateCommand(AddInstancesCommandExecuted);
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecuted);
AddInstancesCommand = new DelegateCommand(AddInstancesCommandExecute);
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute);
}
#endregion
#region Data
public override async Task LoadData()
{
List<Connection> list = await _ConnectionService.GetConnectionList();
if (_BFFHService.ActiveConnection != null)
IList<Connection> list = await _BFFHService.GetConnections().ConfigureAwait(false);
if (_BFFHService.IsConnected)
{
ActiveConnection = new List<ServerListItemViewModel>
{
new ServerListItemViewModel(_BFFHService.ActiveConnection)
new ServerListItemViewModel(_BFFHService.CurrentConnection),
};
list.Remove(_BFFHService.ActiveConnection);
list.Remove(_BFFHService.CurrentConnection);
HasActiveConnection = true;
}
@ -57,16 +54,16 @@ namespace Borepin.PageModel
}
#endregion
#region Properties
private List<ServerListItemViewModel> _ServerListItemViewModel_List;
public List<ServerListItemViewModel> ServerListItemViewModel_List
#region Fields
private IList<ServerListItemViewModel> _ServerListItemViewModel_List;
public IList<ServerListItemViewModel> ServerListItemViewModel_List
{
get => _ServerListItemViewModel_List;
set => SetProperty(ref _ServerListItemViewModel_List, value);
}
private List<ServerListItemViewModel> _ActiveConnection;
public List<ServerListItemViewModel> ActiveConnection
private IList<ServerListItemViewModel> _ActiveConnection;
public IList<ServerListItemViewModel> ActiveConnection
{
get => _ActiveConnection;
set => SetProperty(ref _ActiveConnection, value);
@ -87,20 +84,16 @@ namespace Borepin.PageModel
get => _SelectInstanceCommand;
set => SetProperty(ref _SelectInstanceCommand, value);
}
private async void SelectInstanceCommandExecuted(object obj)
public async void SelectInstanceCommandExecute(object obj)
{
ServerListItemViewModel viewmodel = obj as ServerListItemViewModel;
NavigationParameters parameters = new NavigationParameters
{
{ "instance", viewmodel._Instance }
{ "instance", viewmodel.Instance },
};
INavigationResult result = await _NavigationService.NavigateAsync($"ServerPage", parameters);
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
await _NavigationService.NavigateAsync("ServerPage", parameters).ConfigureAwait(false);
}
private ICommand _AddInstancesCommand;
@ -109,13 +102,9 @@ namespace Borepin.PageModel
get => _AddInstancesCommand;
set => SetProperty(ref _AddInstancesCommand, value);
}
private async void AddInstancesCommandExecuted()
public async void AddInstancesCommandExecute()
{
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_HostSelectPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false);
}
#endregion
@ -125,10 +114,9 @@ namespace Borepin.PageModel
}
public override void OnNavigatedTo(INavigationParameters parameters)
public override async void OnNavigatedTo(INavigationParameters parameters)
{
IsBusy = true;
Task.Run(LoadData);
await LoadData().ConfigureAwait(false);
}
#endregion
}

View File

@ -1,12 +1,12 @@
using Borepin.Base;
using Borepin.Model;
using Borepin.Service.BFFH;
using Borepin.Service.Connections;
using Borepin.Service.Credentials;
using Borepin.Service.BFFH.Exceptions;
using Prism.Commands;
using Prism.Navigation;
using Prism.Services;
using Prism.Services.Dialogs;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
@ -14,37 +14,44 @@ namespace Borepin.PageModel
{
public class ServerPageModel : PageModelBase
{
#region Private Properties
#region Private Fields
private readonly IDialogService _DialogService;
private readonly IConnectionService _ConnectionService;
private readonly IBFFHService _BFFHService;
private readonly ICredentialService _CredentialService;
private readonly IPageDialogService _PageDialogService;
#endregion
#region Constructors
public ServerPageModel(INavigationService navigationService, IDialogService dialogService, IConnectionService connectionService, IBFFHService bffhService, ICredentialService credentialService, IPageDialogService pageDialogService) : base(navigationService)
public ServerPageModel(INavigationService navigationService, IDialogService dialogService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService)
{
_DialogService = dialogService;
_ConnectionService = connectionService;
_BFFHService = bffhService;
_CredentialService = credentialService;
_PageDialogService = pageDialogService;
ConnectCommand = new DelegateCommand(async () => await ConnectCommandExecuted());
DeleteCommand = new DelegateCommand(DeleteCommandExecuted);
ConnectCommand = new DelegateCommand(async () => await ConnectCommandExecute().ConfigureAwait(false));
DisconnectCommand = new DelegateCommand(async () => await DisonnectCommandExecute().ConfigureAwait(false));
DeleteCommand = new DelegateCommand(DeleteCommandExecute);
}
#endregion
#region Data
public override Task LoadData()
{
throw new System.NotImplementedException();
if (_BFFHService.CurrentConnection != null && Connection_Item != null)
{
InstanceIsActiveConnection = Connection_Item.Equals(_BFFHService.CurrentConnection);
}
else
{
InstanceIsActiveConnection = false;
}
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region Properties
#region Fields
private Connection _Connection_Item;
public Connection Connection_Item
{
@ -52,11 +59,11 @@ namespace Borepin.PageModel
set => SetProperty(ref _Connection_Item, value);
}
private bool _IsConnected;
public bool IsConnected
private bool _InstanceIsActiveConnection;
public bool InstanceIsActiveConnection
{
get => _IsConnected;
set => SetProperty(ref _IsConnected, value);
get => _InstanceIsActiveConnection;
set => SetProperty(ref _InstanceIsActiveConnection, value);
}
#endregion
@ -67,50 +74,51 @@ namespace Borepin.PageModel
get => _ConnectCommand;
set => SetProperty(ref _ConnectCommand, value);
}
private async Task ConnectCommandExecuted()
public async Task ConnectCommandExecute()
{
IsBusy = true;
if(IsConnected)
{
await _BFFHService.Disconnect();
IsConnected = false;
}
else
{
try
{
await _BFFHService.Connect(Connection_Item);
await _BFFHService.Connect(Connection_Item).ConfigureAwait(true);
}
catch(Capnp.Rpc.RpcException exception) when (exception.Message == "TcpRpcClient is unable to connect")
catch(ConnectingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok");
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
return;
}
if(!await _BFFHService.Authenticate())
catch(AuthenticatingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok");
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false);
IsBusy = false;
return;
}
IsConnected = true;
var result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage");
if (!result.Success)
catch(MissingCredentialsException)
{
System.Diagnostics.Debugger.Break();
}
await _PageDialogService.DisplayAlertAsync("Secure Storage failed", "Unable to load connections from secure storage.\n Please recreate the connection.", "Ok").ConfigureAwait(false);
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
IsBusy = false;
return;
}
IsBusy = false;
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
}
private ICommand _DisconnectCommand;
public ICommand DisconnectCommand
{
get => _DisconnectCommand;
set => SetProperty(ref _DisconnectCommand, value);
}
public async Task DisonnectCommandExecute()
{
await _BFFHService.Disconnect().ConfigureAwait(false);
await LoadData().ConfigureAwait(false);
}
private ICommand _DeleteCommand;
@ -120,43 +128,27 @@ namespace Borepin.PageModel
set => SetProperty(ref _DeleteCommand, value);
}
private void DeleteCommandExecuted()
public void DeleteCommandExecute()
{
DialogParameters parameters = new DialogParameters
{
{ "title", "Delete Server" },
{ "message", "Do you really want to delete this Server?" },
{ "instance", Connection_Item }
{ "instance", Connection_Item },
};
_DialogService.ShowDialog("ConfirmDialog", parameters, DeleteCommandExecuted_Dialog);
_DialogService.ShowDialog("ConfirmDialog", parameters, DeleteCommandExecute_Dialog);
}
private async void DeleteCommandExecuted_Dialog(IDialogResult result)
public async void DeleteCommandExecute_Dialog(IDialogResult result)
{
if(result.Parameters.GetValue<string>("result") == "confirm")
if(string.Equals(result.Parameters.GetValue<string>("result"), "confirm", StringComparison.Ordinal))
{
Connection connection = (Connection)result.Parameters.GetValue<object>("instance");
Connection connection = result.Parameters.GetValue<Connection>("instance");
if(_BFFHService.ActiveConnection != null && connection == _BFFHService.ActiveConnection)
{
await _BFFHService.Disconnect();
}
await _BFFHService.RemoveConnection(connection).ConfigureAwait(false);
await _ConnectionService.RemoveConnection(connection);
await _CredentialService.RemoveCredentialsAsync(connection);
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage");
}
else
{
INavigationParameters parameters = new NavigationParameters()
{
{ "instance" , result.Parameters.GetValue<object>("instance")}
};
OnNavigatedTo(parameters);
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
}
}
#endregion
@ -168,19 +160,13 @@ namespace Borepin.PageModel
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
if(Connection_Item == null)
{
Connection_Item = parameters["instance"] as Connection;
if (_BFFHService.ActiveConnection != null && Connection_Item != null)
{
IsConnected = Connection_Item.Equals(_BFFHService.ActiveConnection);
LoadData();
}
else
{
IsConnected = false;
}
IsBusy = false;
}
#endregion
}

View File

@ -11,7 +11,7 @@ namespace Borepin.PageModel.SetUpProcess
#region Constructors
public ScanPageModel(INavigationService navigationService) : base(navigationService)
{
NextCommand = new DelegateCommand<object>(NextCommandCommandExecuted);
NextCommand = new DelegateCommand<object>(NextCommandCommandExecute);
}
#endregion
@ -29,13 +29,9 @@ namespace Borepin.PageModel.SetUpProcess
get => _NextCommand;
set => SetProperty(ref _NextCommand, value);
}
private async void NextCommandCommandExecuted(object obj)
public async void NextCommandCommandExecute(object obj)
{
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_HostSelectPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
await _NavigationService.NavigateAsync("AddServerProcess_HostSelectPage").ConfigureAwait(false);
}
#endregion

View File

@ -1,6 +1,7 @@
using Borepin.Base;
using Prism.Commands;
using Prism.Navigation;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
@ -11,7 +12,7 @@ namespace Borepin.PageModel.SetUpProcess
#region Constructors
public WelcomePageModel(INavigationService navigationService) : base(navigationService)
{
NextCommand = new DelegateCommand<object>(NextCommandCommandExecuted);
NextCommand = new DelegateCommand<object>(NextCommandCommandExecute);
}
#endregion
@ -29,14 +30,9 @@ namespace Borepin.PageModel.SetUpProcess
get => _NextCommand;
set => SetProperty(ref _NextCommand, value);
}
private async void NextCommandCommandExecuted(object obj)
public async void NextCommandCommandExecute(object obj)
{
//INavigationResult result = await _NavigationService.NavigateAsync("SetUpProcess_ScanPage");
INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_HostSelectPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
await _NavigationService.NavigateAsync("AddServerProcess_SelectServerPage").ConfigureAwait(false);
}
#endregion

View File

@ -0,0 +1,70 @@
using Borepin.Base;
using Borepin.Model;
using Borepin.Service.BFFH;
using Prism.AppModel;
using Prism.Navigation;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Borepin.PageModel
{
public class StartPageModel : PageModelBase, IPageLifecycleAware, IInitialize
{
#region Private Fields
private readonly IBFFHService _BFFHService;
#endregion
#region Constructors
public StartPageModel(INavigationService navigationService, IBFFHService bffhService) : base(navigationService)
{
_BFFHService = bffhService;
}
#endregion
#region LoadData
public override Task LoadData()
{
return Task.CompletedTask;
}
#endregion
#region IInitialize
public void Initialize(INavigationParameters parameters)
{
}
#endregion
#region IPageLifecycleAware
public async void OnAppearing()
{
IList<Connection> connection_list = await _BFFHService.GetConnections().ConfigureAwait(false);
if (connection_list.Count == 0)
{
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/SetUpProcess_WelcomePage").ConfigureAwait(false);
}
else
{
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
}
}
public void OnDisappearing()
{
}
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
}
}

View File

@ -1,82 +0,0 @@
using Borepin.Base;
using Borepin.Model;
using Borepin.Service.Connections;
using Prism.Commands;
using Prism.Navigation;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Borepin.PageModel
{
public class StartUpDistributorPageModel : PageModelBase
{
#region Private Properties
private readonly IConnectionService _ConnectionService;
#endregion
#region Constructors
public StartUpDistributorPageModel(INavigationService navigationService, IConnectionService connectionService) : base(navigationService)
{
_ConnectionService = connectionService;
DistributePageCommand = new DelegateCommand<string>(DistributePageCommandExecuted);
DistributePageCommand.Execute(null);
}
#endregion
#region LoadData
public override Task LoadData()
{
return Task.CompletedTask;
}
#endregion
#region Command
private ICommand _DistributePageCommand;
public ICommand DistributePageCommand
{
get => _DistributePageCommand;
set => SetProperty(ref _DistributePageCommand, value);
}
private async void DistributePageCommandExecuted(string view)
{
List<Connection> connection_list = await _ConnectionService.GetConnectionList();
if (connection_list.Count == 0)
{
INavigationResult result = await _NavigationService.NavigateAsync("MainPage/NavigationPage/SetUpProcess_WelcomePage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
}
else
{
INavigationResult result = await _NavigationService.NavigateAsync("MainPage/NavigationPage/ServerListPage");
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
}
}
}
#endregion
#region Properties
#endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
}
}

View File

@ -1,39 +0,0 @@
using Borepin.Base;
using Prism.Navigation;
using System.Threading.Tasks;
namespace Borepin.PageModel
{
class TestPageModel : PageModelBase
{
#region Contructors
public TestPageModel(INavigationService navigationService) : base(navigationService)
{
}
#endregion
#region Data
public override Task LoadData()
{
Task.Delay(3000);
IsBusy = false;
return Task.CompletedTask;
}
#endregion
#region INavigationService
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
IsBusy = true;
Task.Run(LoadData);
}
#endregion
}
}

View File

@ -1,110 +1,313 @@
using Borepin.Model;
using Borepin.Service.Credentials;
using System;
using Borepin.Model;
using System.Threading.Tasks;
using System.Collections.Generic;
using FabAccessAPI.Schema;
using System;
using Borepin.Service.Storage;
using Borepin.Model.Storage;
using Borepin.Service.BFFH.Exceptions;
using Borepin.Service.Storage.Exceptions;
namespace Borepin.Service.BFFH
{
public class ConnectionActiveException : Exception
{
public ConnectionActiveException()
{
}
public ConnectionActiveException(string message) : base(message)
{
}
public ConnectionActiveException(string message, Exception inner) : base(message, inner)
{
}
}
public class BFFHService : IBFFHService
{
private readonly ICredentialService _CredentialService;
#region Private Fields
private readonly ConnectionStorage _ConnectionStorage;
private readonly ConnectionCredentialStorage _ConnectionCredentialStorage;
private FabAccessAPI.Connection _Connection;
private FabAccessAPI.Connection _APIConnection;
private Connection_Plain _CurrentConnection;
#endregion
public BFFHService(ICredentialService credentialService)
#region Constructors
public BFFHService(IPreferenceStorageService preferenceStorageService, ISecretStorageService secretStorageService)
{
_CredentialService = credentialService;
_ConnectionStorage = new ConnectionStorage(preferenceStorageService);
_ConnectionCredentialStorage = new ConnectionCredentialStorage(secretStorageService);
}
#endregion
#region Fields
/// <summary>
/// Current Connection of Service
/// </summary>
public Connection CurrentConnection
{
get
{
return _CurrentConnection;
}
}
public Connection ActiveConnection { get; private set; }
/// <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;
}
public bool IsAuthenticated { get; private set; }
return false;
}
}
#endregion
#region Methods
/// <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
{
Capnp.Rpc.TcpRpcClient rpcClient = new Capnp.Rpc.TcpRpcClient();
rpcClient.Connect(connection.Address.Host, connection.Address.Port);
await rpcClient.WhenConnected.ConfigureAwait(false);
rpcClient.Dispose();
}
catch
{
return false;
}
return true;
}
/// <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 (_Connection != null || ActiveConnection != null)
if (IsConnected)
{
throw new ConnectionActiveException();
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
{
Capnp.Rpc.TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
_APIConnection = new FabAccessAPI.Connection(rpcClient);
}
catch (Capnp.Rpc.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))
{
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
{
Capnp.Rpc.TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
_APIConnection = new FabAccessAPI.Connection(rpcClient);
}
catch (Capnp.Rpc.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))
{
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
{
Capnp.Rpc.TcpRpcClient rpcClient = await _ConnectAsync(_CurrentConnection.Address.Host, _CurrentConnection.Address.Port).ConfigureAwait(false);
_APIConnection = new FabAccessAPI.Connection(rpcClient);
}
catch (Capnp.Rpc.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<IMachineSystem> GetMachineSystemInterface()
{
if (!IsConnected)
{
await Reconnect().ConfigureAwait(false);
}
return await _APIConnection.AccessMachineSystem().ConfigureAwait(false);
}
public async Task<IUserSystem> GetUserSystemInterface()
{
if (!IsConnected)
{
await Reconnect().ConfigureAwait(false);
}
return await _APIConnection.AccessUserSystem().ConfigureAwait(false);
}
public async Task<IPermissionSystem> GetPermissionSystemInterface()
{
if (!IsConnected)
{
await Reconnect().ConfigureAwait(false);
}
return await _APIConnection.AccessPermissionSystem().ConfigureAwait(false);
}
#endregion
#endregion
#region Private Methods
private static async Task<Capnp.Rpc.TcpRpcClient> _ConnectAsync(string host, int port)
{
Capnp.Rpc.TcpRpcClient rpcClient = new Capnp.Rpc.TcpRpcClient();
rpcClient.Connect(connection.Address.Host, connection.Address.Port);
// IMPORTANT: without ConfigureAwait(false) every Call for CapnProto Runtime deadlocks on Android
rpcClient.Connect(host, port);
await rpcClient.WhenConnected.ConfigureAwait(false);
FabAccessAPI.Connection connection_test = new FabAccessAPI.Connection(rpcClient);
_Connection = connection_test;
ActiveConnection = connection;
return rpcClient;
}
public async Task Disconnect()
private Task<bool> _AuthenticatePlainAsync(string username, string password)
{
_Connection.RpcClient?.Dispose();
_Connection = null;
ActiveConnection = null;
await Task.CompletedTask;
}
public bool CanAuthenticate()
{
return ActiveConnection.AuthenticationTyp == AuthenticationTyp.PLAIN && ActiveConnection.Username != string.Empty;
}
public async Task<bool> Authenticate()
{
string password = await _CredentialService.GetPasswordAsync(ActiveConnection);
return await _Connection.Auth("PLAIN", new Dictionary<string, object> { { "Username", ActiveConnection.Username }, { "Password", password } });
}
public async Task<bool> Authenticate(Connection connection, string password)
{
bool result = await _Connection.Auth("PLAIN", new Dictionary<string, object> { { "Username", ActiveConnection.Username }, { "Password", password } });
if(result == true)
{
await _CredentialService.AddCredentialsAsync(connection, password);
ActiveConnection = connection;
}
return result;
}
public Task<IMachineSystem> GetMachineSystemInterface()
{
return _Connection.AccessMachineSystem();
}
public Task<IUserSystem> GetUserSystemInterface()
{
return _Connection.AccessUserSystem();
}
public Task<IPermissionSystem> GetPermissionSystemInterface()
{
return _Connection.AccessPermissionSystem();
return _APIConnection.Auth("PLAIN", new Dictionary<string, object>(StringComparer.Ordinal) { { "Username", username }, { "Password", password } });
}
#endregion
}
}

View File

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

View File

@ -0,0 +1,22 @@
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

@ -0,0 +1,22 @@
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

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

View File

@ -0,0 +1,22 @@
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

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

View File

@ -1,54 +1,29 @@
using Borepin.Model;
using FabAccessAPI.Schema;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Borepin.Service.BFFH
{
public interface IBFFHService
{
/// <summary>
/// Connection BFFH Service is currently connected
/// </summary>
Connection ActiveConnection { get; }
Connection CurrentConnection { get; }
bool IsConnected { get; }
/// <summary>
/// Connection is connected and authenticated
/// </summary>
bool IsAuthenticated { get; }
Task<IList<Connection>> GetConnections();
Task RemoveConnection(Connection connection);
Task<bool> TestConnection(Connection connection);
/// <summary>
/// Can Connection with Credetials get Authenticated
/// </summary>
/// <returns></returns>
bool CanAuthenticate();
/// <summary>
/// Connect to BFFH Instance
/// </summary>
/// <param name="connection">Connection with address</param>
Task Connect(Connection connection);
/// <summary>
/// Disconnect from BFFH Instance
/// </summary>
Task Connect(Connection connection, string password);
Task Reconnect();
Task Disconnect();
/// <summary>
/// Authenticate with ActiveConnection
/// Load password from SecureStorage
/// </summary>
Task<bool> Authenticate();
/// <summary>
/// Authenticate with ActiveConnection and password
/// If authenticate is successfull, save password to SecureStorage
/// </summary>
/// <param name="connection">address + username</param>
Task<bool> Authenticate(Connection connection, string password);
Task<IMachineSystem> GetMachineSystemInterface();
Task<IUserSystem> GetUserSystemInterface();
Task<IPermissionSystem> GetPermissionSystemInterface();
Task<IUserSystem> GetUserSystemInterface();
}
}

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