Version 3.0.360

This commit is contained in:
Anja 2023-02-22 14:03:35 +01:00
parent 5c0b2e70c9
commit faf68061f4
160 changed files with 2114 additions and 1932 deletions

View file

@ -11,25 +11,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItShared", "..\LockItSh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItBLE", "..\LockItBLE\LockItBLE.csproj", "{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLockItShared", "..\TestLockItShared\TestLockItShared.csproj", "{7E25F58E-62E3-48D7-8115-E33DA67C511E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestShareeLib", "..\TestShareeLib\TestShareeLib.csproj", "{38F340AD-EC12-4BB2-8633-AC5B55C32B77}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLockItBLE", "..\TestLockItBLE\TestLockItBLE.csproj", "{2581E9AD-4F56-431A-AB87-1B6D80D546AA}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "LastenradBayern", "TINK\LastenradBayern.shproj", "{8D4F2CDD-32C6-4AA1-A9E1-7B27BDCEB3A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LastenradBayern.iOS", "TINK.iOS\LastenradBayern.iOS.csproj", "{3A0EF953-1501-4155-B0A0-265EB5FB2975}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFramework", "..\TestFramework\TestFramework.csproj", "{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestSharee", "..\TestSharee\TestSharee.csproj", "{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
TINK\LastenradBayern.projitems*{3a0ef953-1501-4155-b0a0-265eb5fb2975}*SharedItemsImports = 4
TINK\LastenradBayern.projitems*{8d4f2cdd-32c6-4aa1-a9e1-7b27bdceb3a5}*SharedItemsImports = 13
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Ad-Hoc|ARM = Ad-Hoc|ARM
@ -249,150 +237,6 @@ Global
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x64.Build.0 = Release|Any CPU
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x86.ActiveCfg = Release|Any CPU
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|ARM.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhone.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x64.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x64.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x86.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x86.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x86.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|Any CPU.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|ARM.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|ARM.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhone.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhone.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x64.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x64.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x86.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x86.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|Any CPU.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|ARM.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|ARM.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhone.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhone.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x64.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x64.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x86.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x86.Build.0 = Release|Any CPU
{3A0EF953-1501-4155-B0A0-265EB5FB2975}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhoneSimulator
{3A0EF953-1501-4155-B0A0-265EB5FB2975}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhoneSimulator
{3A0EF953-1501-4155-B0A0-265EB5FB2975}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
@ -473,54 +317,6 @@ Global
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x64.Build.0 = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x86.ActiveCfg = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x86.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|Any CPU.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|ARM.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|ARM.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhone.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhone.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x64.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x64.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x86.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -528,6 +324,11 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C6529CD7-C3F7-4E80-89B5-002E2B8E3EB5}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
TINK\LastenradBayern.projitems*{3a0ef953-1501-4155-b0a0-265eb5fb2975}*SharedItemsImports = 4
..\ShareeSharedGuiLib\ShareeSharedGuiLib.projitems*{3a0ef953-1501-4155-b0a0-265eb5fb2975}*SharedItemsImports = 4
TINK\LastenradBayern.projitems*{8d4f2cdd-32c6-4aa1-a9e1-7b27bdceb3a5}*SharedItemsImports = 13
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.DotNetNamingPolicy = $1

View file

@ -57,7 +57,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidLinkMode>None</AndroidLinkMode>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
@ -176,16 +176,16 @@
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable" Version="28.0.0.3" />
<PackageReference Include="Xamarin.AndroidX.Core">
<Version>1.9.0.1</Version>
<Version>1.9.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
<Version>1.3.1.1</Version>
<Version>1.3.1.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Palette">
<Version>1.0.0.15</Version>
<Version>1.0.0.16</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.2.1.8</Version>
<Version>1.2.1.9</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -193,7 +193,7 @@
<Version>2.0.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.4</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms.AppLinks">
@ -203,10 +203,10 @@
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.1.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.1.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="Mono.Android" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.357" android:versionCode="357">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.360" android:versionCode="360">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key>
<string>LastenradBayern</string>
<key>CFBundleVersion</key>
<string>357</string>
<string>360</string>
<key>CFBundleShortVersionString</key>
<string>3.0.357</string>
<string>3.0.360</string>
</dict>
</plist>

View file

@ -25,7 +25,7 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignProvision>VS: com.TeilRad.LastenradBayern Development</CodesignProvision>
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
@ -200,7 +200,7 @@
<Version>2.0.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.4</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps">
<Version>5.0.0</Version>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -126,6 +126,8 @@ namespace TINK
Log.Debug("Get auth cookie.");
IStore store = null;
// Version of last version used or null for initial installation.
// Used for updating purposes.
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
if (new Version(3, 0, 290) <= lastVersion)
{
@ -139,9 +141,11 @@ namespace TINK
Barrel.ApplicationId = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
// Get main thread synchronization context to be able to update gui elements from worker threads.
var context = SynchronizationContext.Current;
var appInfoService = DependencyService.Get<IAppInfo>();
var smartDevice = DependencyService.Get<ISmartDevice>();
const string MERCHANTID = "0000000000";
@ -158,13 +162,14 @@ namespace TINK
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
sessionCookie,
mail,
smartDevice,
expiresAfter),
merchantId: MERCHANTID,
bluetoothService: BluetoothService, /* locksService */
locationPermissionsService: PermissionsService,
locationServicesContainer: LocationServicesContainer,
locksService: null,
device: DependencyService.Get<ISmartDevice>(),
device: smartDevice,
specialFolder: specialFolders,
cipher: new Cipher(),
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),

View file

@ -199,8 +199,8 @@
Grid.Row="13"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.InfoEntry5}"
IsVisible="{Binding TariffDescription.InfoEntry5, Converter={StaticResource Label_Converter}}"
Text= "{Binding TariffDescription.TrackingInfoText}"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}"
Grid.Row="14"
Grid.ColumnSpan="2"/>
</Grid>

View file

@ -79,7 +79,7 @@ namespace TINK.View.BikesAtStation
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
return;
}
@ -88,9 +88,6 @@ namespace TINK.View.BikesAtStation
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new BikesAtStationPageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -103,7 +100,7 @@ namespace TINK.View.BikesAtStation
model.LocksServices.Active,
model.Polling,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this)
{
@ -128,7 +125,7 @@ namespace TINK.View.BikesAtStation
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
}

View file

@ -35,7 +35,7 @@ namespace TINK.View.FindBike
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
return;
}
@ -43,9 +43,6 @@ namespace TINK.View.FindBike
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new FindBikePageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -57,7 +54,7 @@ namespace TINK.View.FindBike
model.LocksServices.Active,
model.Stations,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
@ -78,7 +75,7 @@ namespace TINK.View.FindBike
BindingContext = m_oViewModel;
FindBikeListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
}
/// <summary>

View file

@ -1,4 +1,4 @@
using Plugin.Connectivity;
using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
@ -47,7 +47,7 @@ namespace TINK.View.MyBikes
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
return;
}
@ -56,9 +56,6 @@ namespace TINK.View.MyBikes
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new MyBikesPageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -70,7 +67,7 @@ namespace TINK.View.MyBikes
model.LocksServices.Active,
model.Stations,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
@ -91,7 +88,7 @@ namespace TINK.View.MyBikes
BindingContext = m_oViewModel;
MyBikesListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
}
@ -183,4 +180,4 @@ namespace TINK.View.MyBikes
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
#endif
}
}
}

View file

@ -11,7 +11,7 @@
<PackageReference Include="Plugin.BLE" Version="2.1.3" />
<PackageReference Include="Polly" Version="7.2.3" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.4" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.5" />
</ItemGroup>
<ItemGroup>

View file

@ -154,8 +154,8 @@ namespace TINK.Services.BluetoothLock.BLE
case LockitLockingState.Unknown:
// Expected error. ILockIt count not be opened (Spoke has blocked/ blocks lock, ....)
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Bold was blocked.");
throw new CouldntOpenBoldWasBlockedException();
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Bold status is unknown");
throw new CouldntOpenBoldStatusIsUnknownException();
default:
// Comprises values
@ -270,6 +270,11 @@ namespace TINK.Services.BluetoothLock.BLE
Log.ForContext<LockItEventBased>().Information($"Lock was closed successfully.");
return lockingState;
case LockitLockingState.Open:
// Expected error. ILockIt could not be closed. Bolt was blocked but was opened again.
Log.ForContext<LockItPolling>().Debug($"Closing lock failed. Bold is blocked but was reopened again.");
throw new CouldntCloseBoldBlockedException(LockingState.Open);
default:
// Comprises values
// - LockitLockingState.Open

View file

@ -120,8 +120,8 @@ namespace TINK.Services.BluetoothLock.BLE
case LockitLockingState.Unknown:
// Expected error. ILockIt count not be opened (Spoke has blocked/ blocks lock, ....)
Log.ForContext<LockItPolling>().Debug($"Opening lock failed. Bold was blocked.");
throw new CouldntOpenBoldWasBlockedException();
Log.ForContext<LockItPolling>().Debug($"Opening lock failed. Bold status is unknown.");
throw new CouldntOpenBoldStatusIsUnknownException();
default:
// Comprises values
@ -181,13 +181,29 @@ namespace TINK.Services.BluetoothLock.BLE
var watch = new Stopwatch();
watch.Start();
var hasBeenLocked = false;
while (info.State != null
&& info.State.Value != LockitLockingState.CouldntCloseBoldBlocked
&& info.State.Value != LockitLockingState.CouldntCloseMoving
&& info.State.Value != LockitLockingState.Closed
&& watch.Elapsed < TimeSpan.FromMilliseconds(OPEN_CLOSE_TIMEOUT_MS))
{
info = await GetLockStateAsync(true); ; // While closing lock seems not always respond to reading operations.
if (info.State.Value == LockitLockingState.CouldntCloseBoldBlocked)
{
// Lock reported a blocked bold.
hasBeenLocked = true;
Log.ForContext<LockItPolling>().Debug($"Waiting for lock to close. Bold is blocked.");
continue;
}
if (hasBeenLocked && info.State.Value == LockitLockingState.Open)
{
// ILockIt could not be closed. Bolt was blocked but was opened again.
Log.ForContext<LockItPolling>().Debug($"Closing lock failed. Bold was blocked and lock was reopened.");
throw new CouldntCloseBoldBlockedException(LockingState.Open);
}
Log.ForContext<LockItPolling>().Debug($"Waiting for lock to close. Current lock state is {info?.State.Value}.");
}

View file

@ -1,4 +1,4 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
@ -144,18 +144,18 @@ namespace TINK.MultilingualResources {
/// <summary>
/// Looks up a localized string similar to Bold is blocked..
/// </summary>
internal static string ErrorOpenLockBoldBlocked {
internal static string ErrorOpenLockBoldIsBlocked {
get {
return ResourceManager.GetString("ErrorOpenLockBoldBlocked", resourceCulture);
return ResourceManager.GetString("ErrorOpenLockBoldIsBlocked", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bold was or is blocked..
/// Looks up a localized string similar to Bold status is unknown..
/// </summary>
internal static string ErrorOpenLockBoldWasBlocked {
internal static string ErrorOpenLockBoldStatusIsUnknown {
get {
return ResourceManager.GetString("ErrorOpenLockBoldWasBlocked", resourceCulture);
return ResourceManager.GetString("ErrorOpenLockBoldStatusIsUnknown", resourceCulture);
}
}

View file

@ -1,11 +1,20 @@
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
namespace TINK.Services.BluetoothLock.Exception
{
public class CouldntCloseBoldBlockedException : StateAwareException
{
public CouldntCloseBoldBlockedException() : base(
LockingState.UnknownFromHardwareError, // Lock is closed in most cases, but this is not guaranteed according to haveltec.
/// <summary>
/// Constructs a bold blocked exception.
/// </summary>
/// <remarks>
/// Lock is closed in most cases, but this is not guaranteed according to haveltec.
/// </remarks>
/// <param name="state">State of the lock while/ after bold blocked event.</param>
/// <remarks>
/// </remarks>
public CouldntCloseBoldBlockedException(LockingState state = LockingState.UnknownFromHardwareError) : base(
state,
MultilingualResources.Resources.ErrorCloseLockBoldBlocked)
{
}

View file

@ -1,4 +1,4 @@
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
namespace TINK.Services.BluetoothLock.Exception
{
@ -9,7 +9,7 @@ namespace TINK.Services.BluetoothLock.Exception
{
public CouldntOpenBoldIsBlockedException() : base(
LockingState.UnknownFromHardwareError,
MultilingualResources.Resources.ErrorOpenLockBoldBlocked)
MultilingualResources.Resources.ErrorOpenLockBoldIsBlocked)
{
}
}

View file

@ -1,15 +1,15 @@
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
namespace TINK.Services.BluetoothLock.Exception
{
/// <summary>
/// Lock can not be opened, because bold is/ was blocked. Obstacle might no more block but lock could not be opened completely to obstacle.
/// </summary>
public class CouldntOpenBoldWasBlockedException : StateAwareException
public class CouldntOpenBoldStatusIsUnknownException : StateAwareException
{
public CouldntOpenBoldWasBlockedException() : base(
public CouldntOpenBoldStatusIsUnknownException() : base(
LockingState.UnknownFromHardwareError,
MultilingualResources.Resources.ErrorOpenLockBoldWasBlocked)
MultilingualResources.Resources.ErrorOpenLockBoldStatusIsUnknown)
{
}
}

View file

@ -11,20 +11,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItShared", "..\LockItSh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItBLE", "..\LockItBLE\LockItBLE.csproj", "{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLockItShared", "..\TestLockItShared\TestLockItShared.csproj", "{7E25F58E-62E3-48D7-8115-E33DA67C511E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestShareeLib", "..\TestShareeLib\TestShareeLib.csproj", "{38F340AD-EC12-4BB2-8633-AC5B55C32B77}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLockItBLE", "..\TestLockItBLE\TestLockItBLE.csproj", "{2581E9AD-4F56-431A-AB87-1B6D80D546AA}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Meinkonrad", "TINK\Meinkonrad.shproj", "{5CF95CB1-AD37-4DBA-8B9D-651CFB9EB903}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meinkonrad.iOS", "TINK.iOS\Meinkonrad.iOS.csproj", "{CF1B848A-D1DF-40AB-BA6F-B1E1746A1161}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFramework", "..\TestFramework\TestFramework.csproj", "{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestSharee", "..\TestSharee\TestSharee.csproj", "{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
@ -245,150 +237,6 @@ Global
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x64.Build.0 = Release|Any CPU
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x86.ActiveCfg = Release|Any CPU
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|ARM.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhone.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x64.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x64.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x86.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x86.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x86.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|Any CPU.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|ARM.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|ARM.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhone.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhone.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x64.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x64.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x86.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x86.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|Any CPU.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|ARM.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|ARM.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhone.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhone.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x64.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x64.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x86.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x86.Build.0 = Release|Any CPU
{CF1B848A-D1DF-40AB-BA6F-B1E1746A1161}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhoneSimulator
{CF1B848A-D1DF-40AB-BA6F-B1E1746A1161}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhoneSimulator
{CF1B848A-D1DF-40AB-BA6F-B1E1746A1161}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
@ -469,54 +317,6 @@ Global
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x64.Build.0 = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x86.ActiveCfg = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x86.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|Any CPU.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|ARM.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|ARM.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhone.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhone.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x64.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x64.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x86.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -527,6 +327,7 @@ Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
TINK\Meinkonrad.projitems*{5cf95cb1-ad37-4dba-8b9d-651cfb9eb903}*SharedItemsImports = 13
TINK\Meinkonrad.projitems*{cf1b848a-d1df-40ab-ba6f-b1e1746a1161}*SharedItemsImports = 4
..\ShareeSharedGuiLib\ShareeSharedGuiLib.projitems*{cf1b848a-d1df-40ab-ba6f-b1e1746a1161}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0

View file

@ -57,7 +57,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidLinkMode>None</AndroidLinkMode>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
@ -176,16 +176,16 @@
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable" Version="28.0.0.3" />
<PackageReference Include="Xamarin.AndroidX.Core">
<Version>1.9.0.1</Version>
<Version>1.9.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
<Version>1.3.1.1</Version>
<Version>1.3.1.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Palette">
<Version>1.0.0.15</Version>
<Version>1.0.0.16</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.2.1.8</Version>
<Version>1.2.1.9</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -193,7 +193,7 @@
<Version>2.0.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.4</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms.AppLinks">
@ -203,10 +203,10 @@
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.1.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.1.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="Mono.Android" />

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.357" android:versionCode="357">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.360" android:versionCode="360">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key>
<string>Mein konrad</string>
<key>CFBundleVersion</key>
<string>357</string>
<string>360</string>
<key>CFBundleShortVersionString</key>
<string>3.0.357</string>
<string>3.0.360</string>
</dict>
</plist>

View file

@ -25,7 +25,7 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignProvision>Automatic</CodesignProvision>
<CodesignKey>Apple Development: Oliver Hauff (947JH7MS9L)</CodesignKey>
@ -201,7 +201,7 @@
<Version>2.0.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.4</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps">
<Version>5.0.0</Version>

View file

@ -27,10 +27,10 @@
<x:String x:Key="EyeOpen">&#xf06e;</x:String>
<x:String x:Key="EyeClose">&#xf070;</x:String>
<!--Triangle exclamation-->
<x:String x:Key="Attention">&#xf071;</x:String>
<!-- Add more resources here -->
<!--Arrow down from line-->
<x:String x:Key="ArrowDown">&#xf063;</x:String>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->
<themes:Konrad/>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -125,6 +125,8 @@ namespace TINK
Log.Debug("Get auth cookie.");
IStore store = null;
// Version of last version used or null for initial installation.
// Used for updating purposes.
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
if (new Version(3, 0, 290) <= lastVersion)
{
@ -138,9 +140,11 @@ namespace TINK
Barrel.ApplicationId = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
// Get main thread synchronization context to be able to update gui elements from worker threads.
var context = SynchronizationContext.Current;
var appInfoService = DependencyService.Get<IAppInfo>();
var smartDevice = DependencyService.Get<ISmartDevice>();
const string MERCHANTID = "0000000000";
@ -157,13 +161,14 @@ namespace TINK
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
sessionCookie,
mail,
smartDevice,
expiresAfter),
merchantId: MERCHANTID,
bluetoothService: BluetoothService, /* locksService */
locationPermissionsService: PermissionsService,
locationServicesContainer: LocationServicesContainer,
locksService: null,
device: DependencyService.Get<ISmartDevice>(),
device: smartDevice,
specialFolder: specialFolders,
cipher: new Cipher(),
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),

View file

@ -69,32 +69,13 @@
IsVisible="{Binding IsButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnButtonClicked}"/>
<Button
<Button
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnLockitButtonClicked}"/>
<!--Hint for Cache Daten.-->
<StackLayout
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
IsVisible="{Binding IsDataFromCache}">
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource Attention}"
Color="Red"
FontFamily="FA-S"
Size="Small"/>
</Image.Source>
</Image>
<Label
TextColor="Red"
FontSize="Small"
Text="{x:Static resources:AppResources.MarkingDataIsFromCache}"/>
</StackLayout>
<!-- Rental description (tarif name, options and rental info -->
<!-- Rental description (tarif name, options and rental info -->
<Grid
RowSpacing="0"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
@ -237,8 +218,8 @@
Grid.Row="13"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.InfoEntry5}"
IsVisible="{Binding TariffDescription.InfoEntry5, Converter={StaticResource Label_Converter}}"
Text= "{Binding TariffDescription.TrackingInfoText}"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}"
Grid.Row="14"
Grid.ColumnSpan="2"/>
</Grid>

View file

@ -27,93 +27,108 @@
<!--Grid for Bike(s) view and Running process in same row-->
<Grid>
<Frame
Grid.Row="0">
<StackLayout Grid.Row="0" Spacing="0">
<!-- Grid for Content -->
<Grid
RowDefinitions="Auto,1*,Auto,Auto">
<!--No Network Connection-->
<sharedGui:NotConnectedToNetView/>
<!--Station-->
<StackLayout
Grid.Row="0"
Orientation="Vertical">
<Frame>
<!--Title-->
<Label
HorizontalOptions="Center"
FontAttributes="Bold"
TextColor="{DynamicResource primary-back-title-color}"
Text="{Binding StationDetailText}"/>
<!-- Grid for Content -->
<Grid
RowDefinitions="Auto,1*,Auto,Auto">
<!--Line-->
<BoxView
HeightRequest="1"
Color="{DynamicResource primary-back-title-color}"/>
<!--Station-->
<StackLayout
Orientation="Vertical">
</StackLayout>
<!--Title-->
<Label
HorizontalOptions="Center"
FontAttributes="Bold"
TextColor="{DynamicResource primary-back-title-color}"
Text="{Binding StationDetailText}"/>
<!--Bike(s)-->
<ListView Grid.Row="1"
x:Name="BikesAtStationListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--Line-->
<BoxView
HeightRequest="1"
Color="{DynamicResource primary-back-title-color}"/>
<!--No Bikes-->
<Label Grid.Row="1"
IsVisible="{Binding IsNoBikesAtStationVisible}"
Text="{Binding NoBikesAtStationText}"/>
</StackLayout>
<!--Info text-->
<Label
Grid.Row="2"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
<!--Bike(s)-->
<StackLayout
Spacing="0"
Grid.Row="1"
IsVisible="{Binding IsBikesListVisible}"
Orientation="Vertical">
<!-- Contact and Login at end of page-->
<StackLayout
Grid.Row="3"
Orientation="Vertical">
<!--Hint for Outdated Data.-->
<sharedGui:HintForRefreshingPageView/>
<!--Line-->
<BoxView
HeightRequest="1"
Color="{DynamicResource primary-back-title-color}"/>
<ListView
x:Name="BikesAtStationListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--Contact to operator-->
<Label
TextType="Html"
Text="{Binding ContactSupportHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
<!--Login required-->
<Label
IsVisible="{Binding IsLoginRequiredHintVisible}"
TextType="Html"
Text="{Binding LoginRequiredHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<!--No Bikes-->
<Label
IsVisible="{Binding IsNoBikesAtStationVisible}"
Text="{Binding NoBikesAtStationText}"/>
</StackLayout>
<!--Info text-->
<Label
Grid.Row="2"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
<!-- Contact and Login at end of page-->
<StackLayout
Grid.Row="3"
Orientation="Vertical">
</Frame>
<!--Line-->
<BoxView
HeightRequest="1"
Color="{DynamicResource primary-back-title-color}"/>
<!--Contact to operator-->
<Label
TextType="Html"
Text="{Binding ContactSupportHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<!--Login required-->
<Label
IsVisible="{Binding IsLoginRequiredHintVisible}"
TextType="Html"
Text="{Binding LoginRequiredHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</Grid>
</Frame>
</StackLayout>
<!--While process is running-->
<sharedGui:RunningProcessView

View file

@ -80,7 +80,7 @@ namespace TINK.View.BikesAtStation
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
return;
}
@ -89,9 +89,6 @@ namespace TINK.View.BikesAtStation
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new BikesAtStationPageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -104,7 +101,7 @@ namespace TINK.View.BikesAtStation
model.LocksServices.Active,
model.Polling,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this)
{
@ -129,7 +126,7 @@ namespace TINK.View.BikesAtStation
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
}

View file

@ -23,44 +23,56 @@
<!--Grid for Bike(s) view and Running process in same row-->
<Grid>
<StackLayout Grid.Row="0">
<Frame
Grid.Row="0">
<!--No Network Connection-->
<sharedGui:NotConnectedToNetView/>
<Grid
<Frame>
<Grid
RowDefinitions="1*,32">
<!--Search bike-->
<StackLayout Grid.Row="0">
<Entry
<!--Search bike-->
<StackLayout>
<Entry
Placeholder="{x:Static resources:AppResources.PlaceholderFindBike}"
IsVisible="{Binding IsSelectBikeVisible}"
MaxLength="10"
CursorPosition="0"
Text="{Binding BikeIdUserInput}"/>
<Button
<Button
Text="{x:Static resources:AppResources.MarkingFindBike}"
IsEnabled="{Binding IsSelectBikeEnabled}"
IsVisible="{Binding IsSelectBikeVisible}"
Command="{Binding OnSelectBikeRequest}"/>
<ListView
<StackLayout
Spacing="0"
IsVisible="{Binding IsBikesListVisible}"
Orientation="Vertical">
<!--Hint for Outdated Data.-->
<sharedGui:HintForRefreshingPageView/>
<ListView
x:Name="FindBikeListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
</StackLayout>
</StackLayout>
<!--Info text-->
<Label
</StackLayout>
<!--Info text-->
<Label
Grid.Row="1"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
@ -68,9 +80,11 @@
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
</Grid>
</Frame>
</Frame>
</StackLayout>
<!--While process is running-->
<sharedGui:RunningProcessView

View file

@ -34,7 +34,7 @@ namespace TINK.View.FindBike
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
return;
}
@ -42,9 +42,6 @@ namespace TINK.View.FindBike
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new FindBikePageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -56,7 +53,7 @@ namespace TINK.View.FindBike
model.LocksServices.Active,
model.Stations,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
@ -77,7 +74,7 @@ namespace TINK.View.FindBike
BindingContext = m_oViewModel;
FindBikeListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
}
/// <summary>

View file

@ -20,14 +20,22 @@
<ContentPage.Content>
<!--Grid for Map with Buttons and Running process-->
<Grid
<Grid>
<StackLayout
Spacing="0"
Grid.Row="0">
<sharedGui:NotConnectedToNetView/>
<Grid Grid.Row="1"
RowDefinitions="3,46,1*,32"
ColumnDefinitions="1*,Auto,1*"
IsEnabled="{Binding IsMapPageEnabled}"
VerticalOptions="FillAndExpand">
<!--Map-->
<maps:Map
<!--Map-->
<maps:Map
Grid.RowSpan="3"
Grid.ColumnSpan="3"
WidthRequest="320"
@ -35,14 +43,14 @@
x:Name="MyMap"
MyLocationEnabled="True"
MapType="Street">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
</maps:Map.Behaviors>
</maps:Map>
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
</maps:Map.Behaviors>
</maps:Map>
<!--Buttons for choosing bike type-->
<Frame
<!--Buttons for choosing bike type-->
<Frame
CornerRadius="13"
Grid.Row="1"
Grid.Column="1"
@ -50,11 +58,11 @@
Padding="0"
IsVisible="{Binding IsNavBarVisible}"
BackgroundColor="{DynamicResource secondary-back-title-color}">
<StackLayout
<StackLayout
Orientation="Horizontal"
Margin="0"
Padding="0">
<Button
<Button
x:Name="KonradButton"
AutomationId ="FilterKonrad_button"
Text="{x:Static resources:AppResources.MarkingCityBike}"
@ -72,8 +80,8 @@
FontSize="Small"
FontAttributes="Bold"
TextColor="{Binding NoKonradColor}">
</Button>
<Button
</Button>
<Button
x:Name="TINKButton"
AutomationId ="FilterTINK_button"
Text="{x:Static resources:AppResources.MarkingCargoBike}"
@ -91,12 +99,12 @@
FontSize="Small"
FontAttributes="Bold"
TextColor="{Binding NoTinkColor}">
</Button>
</StackLayout>
</Frame>
</Button>
</StackLayout>
</Frame>
<!--Info text-->
<Label
<!--Info text-->
<Label
Grid.Row="3"
Grid.ColumnSpan="3"
Text="{Binding StatusInfoText}"
@ -106,11 +114,14 @@
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
</StackLayout>
<!--While process is running-->
<sharedGui:RunningProcessView
IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.RowSpan="4"
Grid.ColumnSpan="3"/>
Grid.Row="0"/>
</Grid>

View file

@ -27,35 +27,47 @@
<!--Grid for Bike(s) view and Running process in same row-->
<Grid>
<Frame
Grid.Row="0">
<StackLayout Grid.Row="0">
<!--Bike(s) view-->
<Grid
<!--No Network Connection-->
<sharedGui:NotConnectedToNetView/>
<Frame>
<!--Bike(s) view-->
<Grid
RowDefinitions="1*,32">
<!--Bike(s)-->
<ListView
Grid.Row="0"
<!--Bike(s)-->
<StackLayout
Spacing="0"
IsVisible="{Binding IsBikesListVisible}"
Orientation="Vertical">
<!--Hint for Outdated Data.-->
<sharedGui:HintForRefreshingPageView/>
<ListView
x:Name="MyBikesListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--No Bikes-->
<Label
</StackLayout>
<!--No Bikes-->
<Label
Grid.Row="0"
IsVisible="{Binding IsNoBikesOccupiedVisible}"
Text="{Binding NoBikesOccupiedText}"/>
<!--Info text-->
<Label
<!--Info text-->
<Label
Grid.Row="1"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
@ -63,9 +75,11 @@
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
</Grid>
</Frame>
</Frame>
</StackLayout>
<!--While process is running-->
<sharedGui:RunningProcessView

View file

@ -1,4 +1,4 @@
using Plugin.Connectivity;
using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
@ -47,7 +47,7 @@ namespace TINK.View.MyBikes
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
return;
}
@ -56,9 +56,6 @@ namespace TINK.View.MyBikes
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new MyBikesPageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -70,7 +67,7 @@ namespace TINK.View.MyBikes
model.LocksServices.Active,
model.Stations,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
@ -91,7 +88,7 @@ namespace TINK.View.MyBikes
BindingContext = m_oViewModel;
MyBikesListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
}
@ -183,4 +180,4 @@ namespace TINK.View.MyBikes
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
#endif
}
}
}

View file

@ -21,6 +21,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Bar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\BarLevelInputViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\BarLevelViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\NotConnectedToNetViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\BarLevelInputView.xaml.cs">
<DependentUpon>BarLevelInputView.xaml</DependentUpon>
<SubType>Code</SubType>
@ -29,6 +30,12 @@
<DependentUpon>BarLevelView.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\HintForRefreshingPageView.xaml.cs">
<DependentUpon>HintForRefreshingPageView.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\NotConnectedToNetView.xaml.cs">
<DependentUpon>NotConnectedToNetView.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RunningProcessView.xaml.cs">
<DependentUpon>RunningProcessView.xaml</DependentUpon>
<SubType>Code</SubType>
@ -67,4 +74,16 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\NotConnectedToNetView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\HintForRefreshingPageView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

View file

@ -0,0 +1,41 @@
<?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:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="ShareeSharedGuiLib.View.HintForRefreshingPageView">
<StackLayout
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
IsVisible="{Binding IsBikesDataOutdatedLabelVisible}"
Padding="0"
Spacing="0"
Margin="0">
<StackLayout.Triggers>
<DataTrigger TargetType="StackLayout"
Binding="{Binding IsBikesDataOutdatedLabelVisible}"
Value="false">
<Setter Property="HeightRequest" Value="0" />
</DataTrigger>
</StackLayout.Triggers>
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource ArrowDown}"
Color="DimGray"
FontFamily="FA-S"
Size="Small"/>
</Image.Source>
</Image>
<Label
TextColor="DimGray"
FontSize="Small"
Padding="5"
Text="{x:Static resources:AppResources.MarkingDataIsFromCache}"/>
</StackLayout>
</ContentView>

View file

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ShareeSharedGuiLib.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace ShareeSharedGuiLib.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HintForRefreshingPageView : ContentView
{
public HintForRefreshingPageView()
{
InitializeComponent();
this.BindingContext = new NotConnectedToNetViewModel();
}
}
}

View file

@ -0,0 +1,31 @@
<?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:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="ShareeSharedGuiLib.View.NotConnectedToNetView">
<StackLayout
BackgroundColor="{x:DynamicResource attention-color}"
IsVisible="{Binding IsNotConnectedToNet}"
Padding="0"
Spacing="0"
Margin="0">
<StackLayout.Triggers>
<DataTrigger TargetType="StackLayout"
Binding="{Binding IsNotConnectedToNet}"
Value="false">
<Setter Property="HeightRequest" Value="0" />
</DataTrigger>
</StackLayout.Triggers>
<Label Text="{x:Static resources:AppResources.MarkingNoNetworkConnection}"
TextColor="White"
FontSize="Small"
Padding="5"
HorizontalTextAlignment="Center"
HorizontalOptions="CenterAndExpand"/>
</StackLayout>
</ContentView>

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ShareeSharedGuiLib.ViewModel;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace ShareeSharedGuiLib.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class NotConnectedToNetView : ContentView, INotifyPropertyChanged
{
public NotConnectedToNetView()
{
InitializeComponent();
this.BindingContext = new NotConnectedToNetViewModel();
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using TINK.MultilingualResources;
using Xamarin.Essentials;
namespace ShareeSharedGuiLib.ViewModel
{
public class NotConnectedToNetViewModel : INotifyPropertyChanged
{
public bool IsNotConnectedToNet { get; set; }
private bool _isBikesDataOutdatedLabelVisible = false;
public event PropertyChangedEventHandler PropertyChanged;
public bool IsBikesDataOutdatedLabelVisible
{
get { return _isBikesDataOutdatedLabelVisible; }
set
{
_isBikesDataOutdatedLabelVisible = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsBikesDataOutdatedLabelVisible)));
}
}
public NotConnectedToNetViewModel()
{
IsNotConnectedToNet = Connectivity.NetworkAccess != NetworkAccess.Internet;
// Register for connectivity changes, be sure to unsubscribe when finished
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
}
public async void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e)
{
IsNotConnectedToNet = e.NetworkAccess != NetworkAccess.Internet;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsNotConnectedToNet)));
if (IsNotConnectedToNet)
{
IsBikesDataOutdatedLabelVisible = false;
}
else
{
IsBikesDataOutdatedLabelVisible = true;
await Task.Delay(TimeSpan.FromSeconds(5));
IsBikesDataOutdatedLabelVisible = false;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsBikesDataOutdatedLabelVisible)));
}
}
}

View file

@ -15,21 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItShared", "..\LockItSh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItBLE", "..\LockItBLE\LockItBLE.csproj", "{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLockItShared", "..\TestLockItShared\TestLockItShared.csproj", "{7E25F58E-62E3-48D7-8115-E33DA67C511E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestShareeLib", "..\TestShareeLib\TestShareeLib.csproj", "{38F340AD-EC12-4BB2-8633-AC5B55C32B77}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLockItBLE", "..\TestLockItBLE\TestLockItBLE.csproj", "{2581E9AD-4F56-431A-AB87-1B6D80D546AA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFramework", "..\TestFramework\TestFramework.csproj", "{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestSharee", "..\TestSharee\TestSharee.csproj", "{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
TINK\TINK.projitems*{5297504f-603f-4e1a-98aa-57c4a0d9d833}*SharedItemsImports = 13
TINK\TINK.projitems*{f2d8208f-a8bf-4403-b0ae-2a1d270e4dc9}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Ad-Hoc|ARM = Ad-Hoc|ARM
@ -282,150 +270,6 @@ Global
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x64.Build.0 = Release|Any CPU
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x86.ActiveCfg = Release|Any CPU
{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}.Release|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Ad-Hoc|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.AppStore|x86.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|ARM.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhone.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x64.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x64.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x86.ActiveCfg = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Debug|x86.Build.0 = Debug|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|Any CPU.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|ARM.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|ARM.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhone.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhone.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x64.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x64.Build.0 = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x86.ActiveCfg = Release|Any CPU
{7E25F58E-62E3-48D7-8115-E33DA67C511E}.Release|x86.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.AppStore|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|ARM.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|ARM.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhone.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x64.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x64.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x86.ActiveCfg = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Debug|x86.Build.0 = Debug|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|Any CPU.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|ARM.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|ARM.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhone.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhone.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x64.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x64.Build.0 = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x86.ActiveCfg = Release|Any CPU
{38F340AD-EC12-4BB2-8633-AC5B55C32B77}.Release|x86.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.AppStore|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|ARM.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhone.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x64.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x64.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x86.ActiveCfg = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Debug|x86.Build.0 = Debug|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|Any CPU.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|ARM.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|ARM.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhone.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhone.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x64.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x64.Build.0 = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x86.ActiveCfg = Release|Any CPU
{2581E9AD-4F56-431A-AB87-1B6D80D546AA}.Release|x86.Build.0 = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
@ -474,54 +318,6 @@ Global
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x64.Build.0 = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x86.ActiveCfg = Release|Any CPU
{9EA4ED8C-C4C3-48DC-8CBE-9281E0A7CA8D}.Release|x86.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.AppStore|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|ARM.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhone.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x64.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x64.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x86.ActiveCfg = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Debug|x86.Build.0 = Debug|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|Any CPU.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|ARM.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|ARM.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhone.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhone.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x64.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x64.Build.0 = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x86.ActiveCfg = Release|Any CPU
{9C80A989-4BBB-4F00-AB5D-45B1F99D5A08}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -529,6 +325,11 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C6529CD7-C3F7-4E80-89B5-002E2B8E3EB5}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
TINK\TINK.projitems*{5297504f-603f-4e1a-98aa-57c4a0d9d833}*SharedItemsImports = 13
..\ShareeSharedGuiLib\ShareeSharedGuiLib.projitems*{f2d8208f-a8bf-4403-b0ae-2a1d270e4dc9}*SharedItemsImports = 4
TINK\TINK.projitems*{f2d8208f-a8bf-4403-b0ae-2a1d270e4dc9}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.DotNetNamingPolicy = $1

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.357" android:versionCode="357">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.360" android:versionCode="360">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -57,7 +57,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
<AndroidLinkMode>None</AndroidLinkMode>
<AotAssemblies>false</AotAssemblies>
<EnableLLVM>false</EnableLLVM>
<AndroidEnableProfiledAot>false</AndroidEnableProfiledAot>
@ -176,16 +176,16 @@
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable" Version="28.0.0.3" />
<PackageReference Include="Xamarin.AndroidX.Core">
<Version>1.9.0.1</Version>
<Version>1.9.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
<Version>1.3.1.1</Version>
<Version>1.3.1.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Palette">
<Version>1.0.0.15</Version>
<Version>1.0.0.16</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.2.1.8</Version>
<Version>1.2.1.9</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -193,7 +193,7 @@
<Version>2.0.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.4</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms.AppLinks">
@ -203,10 +203,10 @@
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.1.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.1.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.1" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.1" />
</ItemGroup>
<ItemGroup>
<Reference Include="Mono.Android" />

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key>
<string>sharee.bike</string>
<key>CFBundleVersion</key>
<string>357</string>
<string>360</string>
<key>CFBundleShortVersionString</key>
<string>3.0.357</string>
<string>3.0.360</string>
</dict>
</plist>

View file

@ -25,7 +25,7 @@
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<CodesignProvision>VS: com.TeilRad.sharee.bike Development</CodesignProvision>
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
@ -94,7 +94,7 @@
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchNoSymbolStrip>
</MtouchNoSymbolStrip>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchLink>None</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<DebugType>none</DebugType>
@ -107,7 +107,7 @@
<CodesignProvision>VS: com.TeilRad.sharee.bike Development</CodesignProvision>
<CodesignKey>Apple Development: Oliver Hauff (8SZ7J9P24J)</CodesignKey>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchLink>SdkOnly</MtouchLink>
<MtouchLink>None</MtouchLink>
</PropertyGroup>
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">
<AppExtensionDebugBundleId />
@ -201,7 +201,7 @@
<Version>2.0.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.4</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps">
<Version>5.0.0</Version>

View file

@ -21,14 +21,17 @@
<x:String x:Key="IconContact">&#xf0e0;</x:String>
<x:String x:Key="IconInfo">&#xf05a;</x:String>
<!--<x:String x:Key="IconClose">&#xf00d;</x:String>-->
<x:String x:Key="IconClose">&#xf410;</x:String>
<x:String x:Key="IconClose">&#xf00d;</x:String>
<!--TogglePasswortEntry-->
<x:String x:Key="EyeOpen">&#xf06e;</x:String>
<x:String x:Key="EyeClose">&#xf070;</x:String>
<!--Triangle exclamation-->
<x:String x:Key="Attention">&#xf071;</x:String>
<!--Arrow down from line-->
<x:String x:Key="ArrowDown">&#xf063;</x:String>
<!--Info in Circle-->
<x:String x:Key="InfoCircle">&#xf05a;</x:String>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -125,6 +125,8 @@ namespace TINK
Log.Debug("Get auth cookie.");
IStore store = null;
// Version of last version used or null for initial installation.
// Used for updating purposes.
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
if (new Version(3, 0, 290) <= lastVersion)
{
@ -138,9 +140,11 @@ namespace TINK
Barrel.ApplicationId = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
// Get main thread synchronization context to be able to update gui elements from worker threads.
var context = SynchronizationContext.Current;
var appInfoService = DependencyService.Get<IAppInfo>();
var smartDevice = DependencyService.Get<ISmartDevice>();
const string MERCHANTID = "0000000000";
@ -157,13 +161,14 @@ namespace TINK
CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
sessionCookie,
mail,
smartDevice,
expiresAfter),
merchantId: MERCHANTID,
bluetoothService: BluetoothService, /* locksService */
locationPermissionsService: PermissionsService,
locationServicesContainer: LocationServicesContainer,
locksService: null,
device: DependencyService.Get<ISmartDevice>(),
device: smartDevice,
specialFolder: specialFolders,
cipher: new Cipher(),
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),

View file

@ -9,231 +9,275 @@
mc:Ignorable="d"
x:Class="TINK.View.Bike.ILockItBike">
<ContentView>
<ContentView.Resources>
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
</ContentView.Resources>
<StackLayout
Padding="10">
<Grid Padding="0,0,5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Icon of the bike -->
<Image
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"
HorizontalOptions="Start"
VerticalOptions="End"
Grid.Column="0"/>
<!-- Battery level -->
<sharedGui:BarLevelView
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
Grid.Column="1"
VerticalOptions="End"
IsVisible="{Binding IsBatteryChargeVisible}"/>
<!-- Name of the bike -->
<StackLayout Grid.Column="1" Grid.ColumnSpan="2">
<Label
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
<!-- Id of the bike -->
<Label
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
</StackLayout>
</Grid>
<!-- Rental state -->
<Label
Text="{Binding StateText}"
TextColor="{Binding StateColor}"/>
<Label
Text="{Binding ErrorText}"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
Command="{Binding OnButtonClicked}"/>
<Button
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
Command="{Binding OnLockitButtonClicked}"/>
<!--Hint for Cache Daten.-->
<StackLayout
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
IsVisible="{Binding IsDataFromCache}">
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource Attention}"
Color="Red"
FontFamily="FA-S"
Size="Small"/>
</Image.Source>
</Image>
<Label
TextColor="Red"
FontSize="Small"
Text="{x:Static resources:AppResources.MarkingDataIsFromCache}"/>
</StackLayout>
<ContentView.Resources>
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
</ContentView.Resources>
<Frame
Padding="10"
Margin="0,5,0,5"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="White">
<StackLayout
Orientation="Vertical"
Padding="10">
<!-- Icons, Name, ID -->
<Grid Padding="0,0,5,10"
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto">
<!-- Icon of the bike -->
<Image
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"
HorizontalOptions="Start"
VerticalOptions="End"/>
<!-- Battery level -->
<sharedGui:BarLevelView
Grid.Column="1"
Grid.Row="1"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
VerticalOptions="End"
IsVisible="{Binding IsBatteryChargeVisible}"/>
<!-- Name of the bike -->
<Label
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="0"
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
<!-- Id of the bike -->
<Label
Grid.Column="2"
Grid.Row="1"
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
</Grid>
<!-- Rental state -->
<Label
Text="{Binding StateText}"
TextColor="{Binding StateColor}"/>
<Label
Text="{Binding ErrorText}"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
<!-- Buttons -->
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
Command="{Binding OnButtonClicked}"/>
<Button
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
Command="{Binding OnLockitButtonClicked}"/>
<!-- Rental description (tarif name, options and rental info -->
<Grid
RowSpacing="0"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
<Grid.RowDefinitions>
<!-- start tarif- entries -->
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<!-- start rental info -->
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
<Grid.RowDefinitions>
<!-- start tarif- entries -->
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<!-- start rental info -->
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Text= "{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionTariffHeader}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
FontAttributes="Bold"/>
<Label
<Label
Text="{Binding TariffDescription.Header}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
Grid.Column="1"
FontAttributes="Bold"/>
<Label
<!--Tracking-->
<Grid
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
ColumnDefinitions="*,Auto"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}">
<Label
Text= "Tracking"
FontAttributes="Bold"
Grid.Column="0"
HorizontalOptions="End"/>
<Button
Command="{Binding ShowTrackingInfoCommand}"
WidthRequest="24"
HeightRequest="24"
BackgroundColor="Transparent"
BorderWidth="0"
Grid.Column="1"
Padding="0"
Margin="0">
<Button.ImageSource>
<FontImageSource
Glyph="{StaticResource InfoCircle}"
Color="DimGray"
FontFamily="FA-S"
Size="20"/>
</Button.ImageSource>
</Button>
</Grid>
<Label
Text= "{Binding TariffDescription.TarifEntry1.Description}"
IsVisible="{Binding TariffDescription.TarifEntry1.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="1"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry1.Value}"
IsVisible="{Binding TariffDescription.TarifEntry1.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="1"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry2.Description}"
IsVisible="{Binding TariffDescription.TarifEntry2.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="2"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry2.Value}"
IsVisible="{Binding TariffDescription.TarifEntry2.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="2"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry3.Description}"
IsVisible="{Binding TariffDescription.TarifEntry3.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="3"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry3.Value}"
IsVisible="{Binding TariffDescription.TarifEntry3.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="3"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry4.Description}"
IsVisible="{Binding TariffDescription.TarifEntry4.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="4"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry4.Value}"
IsVisible="{Binding TariffDescription.TarifEntry4.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="4"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry5.Description}"
IsVisible="{Binding TariffDescription.TarifEntry5.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="5"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry5.Value}"
IsVisible="{Binding TariffDescription.TarifEntry5.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="5"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry6.Description}"
IsVisible="{Binding TariffDescription.TarifEntry6.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="6"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry6.Value}"
IsVisible="{Binding TariffDescription.TarifEntry6.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="6"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry7.Description}"
IsVisible="{Binding TariffDescription.TarifEntry7.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="7"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry7.Value}"
IsVisible="{Binding TariffDescription.TarifEntry7.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="7"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry8.Description}"
IsVisible="{Binding TariffDescription.TarifEntry8.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="8"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry8.Value}"
IsVisible="{Binding TariffDescription.TarifEntry8.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="8"
Grid.Column="1"/>
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry9.Description}"
IsVisible="{Binding TariffDescription.TarifEntry9.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="9"/>
<Label
<Label
Text="{Binding TariffDescription.TarifEntry9.Value}"
IsVisible="{Binding TariffDescription.TarifEntry9.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="9"
Grid.Column="1"/>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Grid.Column="1"
Grid.ColumnSpan="2"/>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Text= "{Binding TariffDescription.InfoEntry1}"
IsVisible="{Binding TariffDescription.InfoEntry1, Converter={StaticResource Label_Converter}}"
Grid.Row="10"
Grid.ColumnSpan="2"/>
<Label
Grid.ColumnSpan="3"/>
<Label
Text= "{Binding TariffDescription.InfoEntry2}"
IsVisible="{Binding TariffDescription.InfoEntry2, Converter={StaticResource Label_Converter}}"
Grid.Row="11"
Grid.ColumnSpan="2"/>
<Label
Grid.ColumnSpan="3"/>
<Label
Text= "{Binding TariffDescription.InfoEntry3}"
IsVisible="{Binding TariffDescription.InfoEntry3, Converter={StaticResource Label_Converter}}"
Grid.Row="12"
Grid.ColumnSpan="2"/>
<Label
Grid.ColumnSpan="3"/>
<Label
Text= "{Binding TariffDescription.InfoEntry4}"
IsVisible="{Binding TariffDescription.InfoEntry4, Converter={StaticResource Label_Converter}}"
Grid.Row="13"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.InfoEntry5}"
IsVisible="{Binding TariffDescription.InfoEntry5, Converter={StaticResource Label_Converter}}"
Grid.Row="14"
Grid.ColumnSpan="2"/>
</Grid>
</StackLayout>
</ContentView>
Grid.ColumnSpan="3"/>
</Grid>
</StackLayout>
</Frame>
</ContentView>
</ViewCell>

View file

@ -7,6 +7,7 @@
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:sharedGui="clr-namespace:ShareeSharedGuiLib.View"
Shell.FlyoutBehavior="Disabled"
BackgroundColor="#f6f6f6"
Shell.NavBarIsVisible="{Binding IsIdle}">
<Shell.TitleView>
@ -26,94 +27,118 @@
<!--Grid for Bike(s) view and Running process in same row-->
<Grid>
<!-- Grid for Content -->
<Grid Grid.Row="0"
RowDefinitions="Auto,1*,Auto">
<Frame
Grid.Row="0">
<!-- Grid for Content -->
<Grid
RowDefinitions="Auto,1*,Auto,Auto">
<StackLayout
Grid.Row="0"
Spacing="0"
Orientation="Vertical">
<!--Station-->
<StackLayout
Grid.Row="0"
Orientation="Vertical">
<!--Title-->
<Label
HorizontalOptions="Center"
FontAttributes="Bold"
TextColor="{DynamicResource primary-back-title-color}"
Text="{Binding StationDetailText}"/>
BackgroundColor="{DynamicResource primary-back-title-color}">
<!--Line-->
<BoxView
HeightRequest="1"
Color="{DynamicResource primary-back-title-color}"/>
HeightRequest="1"
WidthRequest="260"
HorizontalOptions="Center"
Color="White"/>
<!--Title-->
<Label
HorizontalOptions="Center"
FontAttributes="Bold"
Padding="10,0,10,10"
TextColor="White"
Text="{Binding StationDetailText}"/>
</StackLayout>
<!--No Network Connection-->
<sharedGui:NotConnectedToNetView/>
<!--Bike(s)-->
<ListView Grid.Row="1"
<StackLayout
IsVisible="{Binding IsBikesListVisible}"
Spacing="0">
<!--Hint for Outdated Data.-->
<sharedGui:HintForRefreshingPageView/>
<ListView Grid.Row="1"
x:Name="BikesAtStationListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
SeparatorVisibility="None"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--No Bikes-->
<Label Grid.Row="1"
</StackLayout>
</StackLayout>
<!--No Bikes-->
<Label Grid.Row="1" Padding="10"
IsVisible="{Binding IsNoBikesAtStationVisible}"
Text="{Binding NoBikesAtStationText}"/>
<StackLayout
Grid.Row="2"
Orientation="Vertical"
BackgroundColor="{DynamicResource primary-back-title-color}"
Padding="0,0,0,10">
<!--Info text-->
<Label
Grid.Row="2"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small"
Padding="10,5,10,0"
TextColor="White"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
<!-- Contact and Login at end of page-->
<StackLayout
Grid.Row="3"
Orientation="Vertical">
<!--Line-->
<BoxView
<!--Line-->
<BoxView
HeightRequest="1"
Color="{DynamicResource primary-back-title-color}"/>
WidthRequest="260"
HorizontalOptions="Center"
Color="White"/>
<!--Contact to operator-->
<Label
<!--Contact to operator-->
<Label
TextType="Html"
Padding="10,5,10,0"
TextColor="White"
Text="{Binding ContactSupportHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<!--Login required-->
<Label
<!--Login required-->
<Label
IsVisible="{Binding IsLoginRequiredHintVisible}"
TextType="Html"
Padding="10,5,10,0"
TextColor="White"
Text="{Binding LoginRequiredHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</Grid>
<!--While process is running-->
<sharedGui:RunningProcessView

View file

@ -80,7 +80,7 @@ namespace TINK.View.BikesAtStation
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
return;
}
@ -89,9 +89,6 @@ namespace TINK.View.BikesAtStation
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new BikesAtStationPageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -104,7 +101,7 @@ namespace TINK.View.BikesAtStation
model.LocksServices.Active,
model.Polling,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this)
{
@ -129,7 +126,7 @@ namespace TINK.View.BikesAtStation
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
}

View file

@ -5,7 +5,8 @@
x:Class="TINK.View.FindBike.FindBikePage"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:local_bike="clr-namespace:TINK.View.Bike"
xmlns:sharedGui="clr-namespace:ShareeSharedGuiLib.View">
xmlns:sharedGui="clr-namespace:ShareeSharedGuiLib.View"
BackgroundColor="#f6f6f6">
<Shell.TitleView>
<Grid ColumnDefinitions="Auto, 1*">
@ -23,19 +24,28 @@
<ContentPage.Content>
<!--Grid for Bike(s) view and Running process in same row-->
<Grid>
<Grid>
<Frame
Grid.Row="0">
<Grid
RowDefinitions="1*,Auto"
Grid.Row="0">
<Grid
RowDefinitions="1*,32">
<StackLayout
Grid.Row="0"
Spacing="0"
Orientation="Vertical">
<!--No Network Connection-->
<sharedGui:NotConnectedToNetView/>
<!--Search bike-->
<StackLayout Grid.Row="0">
<StackLayout
BackgroundColor="White"
IsVisible="{Binding IsSelectBikeVisible}"
Padding="10">
<Entry
Placeholder="{x:Static resources:AppResources.PlaceholderFindBike}"
IsVisible="{Binding IsSelectBikeVisible}"
MaxLength="10"
CursorPosition="0"
Text="{Binding BikeIdUserInput}"/>
@ -43,35 +53,51 @@
<Button
Text="{x:Static resources:AppResources.MarkingFindBike}"
IsEnabled="{Binding IsSelectBikeEnabled}"
IsVisible="{Binding IsSelectBikeVisible}"
Command="{Binding OnSelectBikeRequest}"/>
<ListView
x:Name="FindBikeListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
</StackLayout>
<!--Info text-->
<!-- Bike -->
<StackLayout
Spacing="0"
IsVisible="{Binding IsBikesListVisible}"
Orientation="Vertical">
<!--Hint for Outdated Data.-->
<sharedGui:HintForRefreshingPageView/>
<ListView
x:Name="FindBikeListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
HasUnevenRows="True"
SeparatorVisibility="None"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
</StackLayout>
</StackLayout>
<!--Info text-->
<StackLayout
BackgroundColor="#f6f6f6"
Padding="10,5,10,10"
Grid.Row="1">
<Label
Grid.Row="1"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
</StackLayout>
</Frame>
</Grid>
<!--While process is running-->
<sharedGui:RunningProcessView

View file

@ -34,7 +34,7 @@ namespace TINK.View.FindBike
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
return;
}
@ -42,9 +42,6 @@ namespace TINK.View.FindBike
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new FindBikePageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -56,7 +53,7 @@ namespace TINK.View.FindBike
model.LocksServices.Active,
model.Stations,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
@ -79,7 +76,7 @@ namespace TINK.View.FindBike
BindingContext = m_oViewModel;
FindBikeListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
}
/// <summary>

View file

@ -19,14 +19,22 @@
<ContentPage.Content>
<!--Grid for Map with Buttons and Running process-->
<Grid
<Grid>
<StackLayout
Spacing="0"
Grid.Row="0">
<sharedGui:NotConnectedToNetView/>
<Grid
RowDefinitions="3,46,1*,32"
ColumnDefinitions="1*,Auto,1*"
IsEnabled="{Binding IsMapPageEnabled}"
VerticalOptions="FillAndExpand">
<!--Map-->
<maps:Map
<!--Map-->
<maps:Map
Grid.RowSpan="3"
Grid.ColumnSpan="3"
WidthRequest="320"
@ -34,14 +42,14 @@
x:Name="MyMap"
MyLocationEnabled="True"
MapType="Street">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
</maps:Map.Behaviors>
</maps:Map>
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
</maps:Map.Behaviors>
</maps:Map>
<!--Buttons for choosing bike type-->
<Frame
<!--Buttons for choosing bike type-->
<Frame
CornerRadius="13"
Grid.Row="1"
Grid.Column="1"
@ -49,11 +57,11 @@
Padding="0"
IsVisible="{Binding IsNavBarVisible}"
BackgroundColor="{DynamicResource secondary-back-title-color}">
<StackLayout
<StackLayout
Orientation="Horizontal"
Margin="0"
Padding="0">
<Button
<Button
x:Name="KonradButton"
AutomationId ="FilterKonrad_button"
Text="{x:Static resources:AppResources.MarkingCityBike}"
@ -71,8 +79,8 @@
FontSize="Small"
FontAttributes="Bold"
TextColor="{Binding NoKonradColor}">
</Button>
<Button
</Button>
<Button
x:Name="TINKButton"
AutomationId ="FilterTINK_button"
Text="{x:Static resources:AppResources.MarkingCargoBike}"
@ -90,12 +98,12 @@
FontSize="Small"
FontAttributes="Bold"
TextColor="{Binding NoTinkColor}">
</Button>
</StackLayout>
</Frame>
</Button>
</StackLayout>
</Frame>
<!--Info text-->
<Label
<!--Info text-->
<Label
Grid.Row="3"
Grid.ColumnSpan="3"
Text="{Binding StatusInfoText}"
@ -105,12 +113,14 @@
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
</StackLayout>
<!--While process is running-->
<sharedGui:RunningProcessView
IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.RowSpan="4"
Grid.ColumnSpan="3"/>
Grid.Row="0"/>
</Grid>
</ContentPage.Content>

View file

@ -6,6 +6,7 @@
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:sharedGui="clr-namespace:ShareeSharedGuiLib.View"
xmlns:local_bike="clr-namespace:TINK.View.Bike"
BackgroundColor="#f6f6f6"
Shell.FlyoutBehavior="{Binding FlyoutBehavior}">
<Shell.TitleView>
@ -26,45 +27,66 @@
<!--Grid for Bike(s) view and Running process in same row-->
<Grid>
<Frame
Grid.Row="0">
<!--Bike(s) view-->
<Grid
RowDefinitions="1*,Auto"
Grid.Row="0">
<!--Bike(s) view-->
<Grid
RowDefinitions="1*,32">
<StackLayout
Grid.Row="0"
Spacing="0"
Orientation="Vertical">
<!--No Network Connection-->
<sharedGui:NotConnectedToNetView/>
<!--Bike(s)-->
<ListView
Grid.Row="0"
<StackLayout
Spacing="0"
IsVisible="{Binding IsBikesListVisible}"
Orientation="Vertical">
<!--Hint for Outdated Data.-->
<sharedGui:HintForRefreshingPageView/>
<ListView
x:Name="MyBikesListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
SeparatorVisibility="None"
ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
</StackLayout>
<!--No Bikes-->
<Label
Grid.Row="0"
Padding="10"
IsVisible="{Binding IsNoBikesOccupiedVisible}"
Text="{Binding NoBikesOccupiedText}"/>
</StackLayout>
<!--Info text-->
<StackLayout
BackgroundColor="#f6f6f6"
Padding="10,5,10,10"
Grid.Row="1">
<!--Info text-->
<Label
Grid.Row="1"
Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/>
</Grid>
</StackLayout>
</Frame>
</Grid>
<!--While process is running-->
<sharedGui:RunningProcessView

View file

@ -1,4 +1,4 @@
using Plugin.Connectivity;
using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
@ -47,7 +47,7 @@ namespace TINK.View.MyBikes
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
return;
}
@ -56,9 +56,6 @@ namespace TINK.View.MyBikes
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new MyBikesPageViewModel(
model.ActiveUser,
App.PermissionsService,
@ -70,7 +67,7 @@ namespace TINK.View.MyBikes
model.LocksServices.Active,
model.Stations,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.PostAction,
model.SmartDevice,
this,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url))
@ -91,7 +88,7 @@ namespace TINK.View.MyBikes
BindingContext = m_oViewModel;
MyBikesListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
await m_oViewModel.OnAppearingOrRefresh();
isInitializationStarted = false;
}
@ -183,4 +180,4 @@ namespace TINK.View.MyBikes
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup(battery, co2Saving));
#endif
}
}
}

View file

@ -35,7 +35,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
public new string ToString()
{
return $"Id={Id}{(TypeOfBike != null ? $";type={TypeOfBike}" : "")};state={State}";
return $"Id={Id}{(TypeOfBike != null ? $";type={TypeOfBike}" : "")};state={State.ToString()}";
}
}
}

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace TINK.Model.Bikes.BikeInfoNS
{
@ -24,9 +24,19 @@ namespace TINK.Model.Bikes.BikeInfoNS
public string Value { get; set; } = string.Empty;
}
/// <summary>
/// Info element of general purpose (AGB, tracking info, ...)
/// </summary>
public class InfoElement
{
/// <summary>
/// Key which identyfies the value (required for special processing)
/// </summary>
public string Key { get; set; }
/// <summary>
/// Text to be displayed to user.
/// </summary>
public string Value { get; set; }
}

View file

@ -286,7 +286,7 @@ namespace TINK.Model.Connector
}
DoReturnResponse response
= (await CopriServer.DoReturn(bike.Id, location, smartDevice, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
= (await CopriServer.DoReturn(bike.Id, location, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
bike.Load(Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.None);
return response?.Create() ?? new BookingFinishedModel();

View file

@ -1,4 +1,5 @@
using System;
using System;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi;
using TINK.Repository;
@ -9,12 +10,13 @@ namespace TINK.Model.Connector
/// </summary>
public class Connector : IConnector
{
/// <summary>Constructs a copri connector object.</summary>
/// <summary>Constructs a copri connector object to connect to copri by https with cache fallback.</summary>
/// <param name="activeUri"> Uri to connect to.</param>
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="sessionCookie"> Holds the session cookie.</param>
/// <param name="mail">Mail of user.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
/// <param name="expiresAfter">Timespan which holds value after which cache expires.</param>
/// <param name="server"> Is null in production and migh be a mock in testing context.</param>
public Connector(
@ -23,25 +25,28 @@ namespace TINK.Model.Connector
string uiIsoLangugageName,
string sessionCookie,
string mail,
ISmartDevice smartDevice = null,
TimeSpan? expiresAfter = null,
ICachedCopriServer server = null)
{
Command = GetCommand(
Command = CreateCommand(
server ?? new CopriProviderHttps(
activeUri,
appContextInfo.MerchantId,
appContextInfo,
uiIsoLangugageName,
smartDevice,
sessionCookie),
sessionCookie,
mail);
Query = GetQuery(
Query = CreateQuery(
server ?? new CopriProviderHttps(
activeUri,
appContextInfo.MerchantId,
appContextInfo,
uiIsoLangugageName,
smartDevice,
sessionCookie,
expiresAfter),
sessionCookie,
@ -57,13 +62,13 @@ namespace TINK.Model.Connector
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>
public bool IsConnected => Command.IsConnected;
/// <summary> Gets a command object to perform copri commands. </summary>
public static ICommand GetCommand(ICopriServerBase copri, string sessioncookie, string mail) => string.IsNullOrEmpty(sessioncookie)
/// <summary> Creates a command object to perform copri commands. </summary>
public static ICommand CreateCommand(ICopriServerBase copri, string sessioncookie, string mail) => string.IsNullOrEmpty(sessioncookie)
? new Command(copri)
: new CommandLoggedIn(copri, sessioncookie, mail, () => DateTime.Now) as ICommand;
/// <summary> Gets a command object to perform copri queries. </summary>
private static IQuery GetQuery(ICachedCopriServer copri, string sessioncookie, string mail) => string.IsNullOrEmpty(sessioncookie)
/// <summary> Creates a command object to perform copri queries. </summary>
private static IQuery CreateQuery(ICachedCopriServer copri, string sessioncookie, string mail) => string.IsNullOrEmpty(sessioncookie)
? new CachedQuery(copri) as IQuery
: new CachedQueryLoggedIn(copri, sessioncookie, mail, () => DateTime.Now);
}

View file

@ -1,4 +1,5 @@
using System;
using System;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi;
using TINK.Repository;
@ -9,26 +10,28 @@ namespace TINK.Model.Connector
/// </summary>
public class ConnectorCache : IConnector
{
/// <summary>Constructs a copri connector object.</summary>
/// <summary>Constructs a copri connector object to connect to cache.</summary>
/// <remarks>Used for offline szenario to ensure responsiveness of app by preventing hopeless tries to communicate with COPRI. </remarks>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="sessionCookie"> Holds the session cookie.</param>
/// <param name="mail">Mail of user.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
/// <param name="server"> Is null in production and migh be a mock in testing context.</param>
public ConnectorCache(
AppContextInfo appContextInfo,
string uiIsoLangugageName,
string sessionCookie,
string mail,
ISmartDevice smartDevice = null,
ICopriServer server = null)
{
Command = Connector.GetCommand(
server ?? new CopriProviderMonkeyStore(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie),
Command = Connector.CreateCommand(
server ?? new CopriProviderMonkeyStore(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie, smartDevice),
sessionCookie,
mail);
Query = GetQuery(
server ?? new CopriProviderMonkeyStore(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie),
server ?? new CopriProviderMonkeyStore(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie, smartDevice),
sessionCookie,
mail);
}

View file

@ -1,4 +1,5 @@
using System;
using System;
using TINK.Model.Device;
using TINK.Repository;
namespace TINK.Model.Connector
@ -8,10 +9,13 @@ namespace TINK.Model.Connector
/// <summary>
/// Gets a connector object depending on whether beein onlin or offline.
/// </summary>
/// <param name="isConnected">True if online, false if offline. If offline cache connector is returned.</param>
/// <param name="isConnected">
/// True if online, false if offline.
/// If offline cache connector is returned to avoid performance penalty which would happen when trying to communicate with backend in offline scenario.
/// </param>
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <returns></returns>
/// <param name="smartDevice">Holds info about smart device.</param>
public static IConnector Create(
bool isConnected,
Uri activeUri,
@ -19,11 +23,12 @@ namespace TINK.Model.Connector
string uiIsoLangugageName,
string sessionCookie,
string mail,
ISmartDevice smartDevice = null,
TimeSpan? expiresAfter = null)
{
return isConnected
? new Connector(activeUri, appContextInfo, uiIsoLangugageName, sessionCookie, mail, expiresAfter: expiresAfter) as IConnector
: new ConnectorCache(appContextInfo, uiIsoLangugageName, sessionCookie, mail);
? new Connector(activeUri, appContextInfo, uiIsoLangugageName, sessionCookie, mail, smartDevice, expiresAfter: expiresAfter) as IConnector
: new ConnectorCache(appContextInfo, uiIsoLangugageName, sessionCookie, mail, smartDevice);
}
}
}

View file

@ -118,12 +118,12 @@ namespace TINK.Model.Settings
}
/// <summary> Sets the uri of the active copri host. </summary>
/// <param name="settingsJSON">Dictionary holding parameters from JSON.</param>
public static Dictionary<string, string> SetCopriHostUri(this IDictionary<string, string> p_oTargetDictionary, string p_strNextActiveUriText)
public static Dictionary<string, string> SetCopriHostUri(this IDictionary<string, string> targetDictionary, string p_strNextActiveUriText)
{
if (p_oTargetDictionary == null)
if (targetDictionary == null)
throw new Exception("Writing copri host uri to dictionary failed. Dictionary must not be null.");
return p_oTargetDictionary.Union(new Dictionary<string, string>
return targetDictionary.Union(new Dictionary<string, string>
{
{ typeof(CopriServerUriList).ToString(), JsonConvert.SerializeObject(p_strNextActiveUriText) },
}).ToDictionary(key => key.Key, value => value.Value);
@ -196,15 +196,17 @@ namespace TINK.Model.Settings
/// <summary> Sets whether polling is on or off and the periode if polling is on. </summary>
/// <param name="settingsJSON">Dictionary to write entries to.</param>
public static Dictionary<string, string> SetPollingParameters(this IDictionary<string, string> p_oTargetDictionary, PollingParameters p_oPollingParameter)
public static Dictionary<string, string> SetPollingParameters(
this IDictionary<string, string> targetDictionary,
PollingParameters pollingParameter)
{
if (p_oTargetDictionary == null)
if (targetDictionary == null)
throw new Exception("Writing polling parameters to dictionary failed. Dictionary must not be null.");
return p_oTargetDictionary.Union(new Dictionary<string, string>
return targetDictionary.Union(new Dictionary<string, string>
{
{ $"{typeof(PollingParameters).Name}_{typeof(TimeSpan).Name}", JsonConvert.SerializeObject(p_oPollingParameter.Periode) },
{ $"{typeof(PollingParameters).Name}_{typeof(bool).Name}", JsonConvert.SerializeObject(p_oPollingParameter.IsActivated) },
{ $"{typeof(PollingParameters).Name}_{typeof(TimeSpan).Name}", JsonConvert.SerializeObject(pollingParameter.Periode) },
{ $"{typeof(PollingParameters).Name}_{typeof(bool).Name}", JsonConvert.SerializeObject(pollingParameter.IsActivated) },
}).ToDictionary(key => key.Key, value => value.Value);
}
@ -242,24 +244,24 @@ namespace TINK.Model.Settings
/// <returns>Dictionary of settings.</returns>
public static Dictionary<string, string> Deserialize(string settingsDirectory)
{
var l_oFileName = $"{settingsDirectory}{System.IO.Path.DirectorySeparatorChar}{SETTINGSFILETITLE}";
var fileName = $"{settingsDirectory}{System.IO.Path.DirectorySeparatorChar}{SETTINGSFILETITLE}";
if (!System.IO.File.Exists(l_oFileName))
if (!System.IO.File.Exists(fileName))
{
// File is empty. Nothing to read.
return new Dictionary<string, string>(); ;
}
var l_oJSONFile = System.IO.File.ReadAllText(l_oFileName);
var jsonFile = System.IO.File.ReadAllText(fileName);
if (string.IsNullOrEmpty(l_oJSONFile))
if (string.IsNullOrEmpty(jsonFile))
{
// File is empty. Nothing to read.
return new Dictionary<string, string>();
}
// Load setting file.
return JsonConvert.DeserializeObject<Dictionary<string, string>>(l_oJSONFile);
return JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonFile);
}
/// <summary> Gets the logging level.</summary>
@ -291,15 +293,15 @@ namespace TINK.Model.Settings
/// <summary> Sets the logging level.</summary>
/// <param name="settingsJSON">Dictionary to get logging level from.</param>
public static Dictionary<string, string> SetMinimumLoggingLevel(this IDictionary<string, string> p_oTargetDictionary, LogEventLevel p_oLevel)
public static Dictionary<string, string> SetMinimumLoggingLevel(this IDictionary<string, string> targetDictionary, LogEventLevel level)
{
// Set logging level.
if (p_oTargetDictionary == null)
if (targetDictionary == null)
throw new Exception("Writing logging level to dictionary failed. Dictionary must not be null.");
return p_oTargetDictionary.Union(new Dictionary<string, string>
return targetDictionary.Union(new Dictionary<string, string>
{
{ MINLOGGINGLEVELKEY, JsonConvert.SerializeObject((int)p_oLevel) }
{ MINLOGGINGLEVELKEY, JsonConvert.SerializeObject((int)level) }
}).ToDictionary(key => key.Key, value => value.Value);
}
@ -321,15 +323,15 @@ namespace TINK.Model.Settings
/// <summary> Sets the version of app when whats new was shown.</summary>
/// <param name="settingsJSON">Dictionary to get information from.</param>
public static Dictionary<string, string> SetWhatsNew(this IDictionary<string, string> p_oTargetDictionary, Version p_oAppVersion)
public static Dictionary<string, string> SetWhatsNew(this IDictionary<string, string> targetDictionary, Version appVersion)
{
// Set logging level.
if (p_oTargetDictionary == null)
if (targetDictionary == null)
throw new Exception("Writing WhatsNew info failed. Dictionary must not be null.");
return p_oTargetDictionary.Union(new Dictionary<string, string>
return targetDictionary.Union(new Dictionary<string, string>
{
{ SHOWWHATSNEWKEY, JsonConvert.SerializeObject(p_oAppVersion, new VersionConverter()) }
{ SHOWWHATSNEWKEY, JsonConvert.SerializeObject(appVersion, new VersionConverter()) }
}).ToDictionary(key => key.Key, value => value.Value);
}
@ -350,12 +352,12 @@ namespace TINK.Model.Settings
/// <summary> Sets the the expiration time.</summary>
/// <param name="settingsJSON">Dictionary to write information to.</param>
public static Dictionary<string, string> SetExpiresAfter(this IDictionary<string, string> p_oTargetDictionary, TimeSpan expiresAfter)
public static Dictionary<string, string> SetExpiresAfter(this IDictionary<string, string> targetDictionary, TimeSpan expiresAfter)
{
if (p_oTargetDictionary == null)
if (targetDictionary == null)
throw new Exception("Writing ExpiresAfter info failed. Dictionary must not be null.");
return p_oTargetDictionary.Union(new Dictionary<string, string>
return targetDictionary.Union(new Dictionary<string, string>
{
{ EXPIRESAFTER, JsonConvert.SerializeObject(expiresAfter, new JavaScriptDateTimeConverter()) }
}).ToDictionary(key => key.Key, value => value.Value);
@ -497,16 +499,16 @@ namespace TINK.Model.Settings
public static IDictionary<string, string> SetGroupFilterMapPage(
this IDictionary<string, string> settings,
IDictionary<string, FilterState> p_oFilterCollection)
IDictionary<string, FilterState> filterCollection)
{
if (settings == null
|| p_oFilterCollection == null
|| p_oFilterCollection.Count < 1)
|| filterCollection == null
|| filterCollection.Count < 1)
{
return settings;
}
settings["FilterCollection_MapPageFilter"] = JsonConvert.SerializeObject(p_oFilterCollection);
settings["FilterCollection_MapPageFilter"] = JsonConvert.SerializeObject(filterCollection);
return settings;
}
@ -541,16 +543,16 @@ namespace TINK.Model.Settings
public static IDictionary<string, string> SetGroupFilterSettings(
this IDictionary<string, string> settings,
IDictionary<string, FilterState> p_oFilterCollection)
IDictionary<string, FilterState> filterCollection)
{
if (settings == null
|| p_oFilterCollection == null
|| p_oFilterCollection.Count < 1)
|| filterCollection == null
|| filterCollection.Count < 1)
{
return settings;
}
settings["FilterCollection"] = JsonConvert.SerializeObject(p_oFilterCollection);
settings["FilterCollection"] = JsonConvert.SerializeObject(filterCollection);
return settings;
}

View file

@ -1,4 +1,4 @@
using System;
using System;
namespace TINK.Settings
{
@ -7,7 +7,7 @@ namespace TINK.Settings
{
/// <summary> Holds default polling parameters. </summary>
public static PollingParameters Default { get; } = new PollingParameters(
new TimeSpan(0, 0, 0, 10 /*secs*/, 0),// Default polling interval.
new TimeSpan(0, 0, 0, 60 /*secs*/, 0), // Default polling interval. Was 10 secs up to 3.0.357.
true);
/// <summary> Holds polling parameters which represent polling off (empty polling object). </summary>
@ -16,12 +16,12 @@ namespace TINK.Settings
false);
/// <summary> Constructs a polling parameter object. </summary>
/// <param name="p_oPeriode">Polling periode.</param>
/// <param name="p_bIsActivated">True if polling is activated.</param>
public PollingParameters(TimeSpan p_oPeriode, bool p_bIsActivated)
/// <param name="periode">Polling periode.</param>
/// <param name="activated">True if polling is activated.</param>
public PollingParameters(TimeSpan periode, bool activated)
{
Periode = p_oPeriode; // Can not be null because is a struct.
IsActivated = p_bIsActivated;
Periode = periode; // Can not be null because is a struct.
IsActivated = activated;
}
/// <summary>Holds the polling periode.</summary>

View file

@ -193,10 +193,13 @@ namespace TINK.Model
?? ((d, obj) => d(obj));
ConnectorFactory = connectorFactory
?? throw new ArgumentException("Can not instantiate TinkApp- object. No connector factory object available.");
?? throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. No connector factory object available.");
MerchantId = merchantId
?? throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}. No merchant id available.");
?? throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. No merchant id available.");
if (settings == null)
throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. Settings must not be null.");
Cipher = cipher ?? new Cipher();
@ -296,8 +299,12 @@ namespace TINK.Model
NextActiveUri = Uris.ActiveUri;
Polling = settings.PollingParameters ??
throw new ArgumentException("Can not instantiate TinkApp- object. Polling parameters must never be null.");
if (settings.PollingParameters == null)
throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. Polling parameters must never be null.");
Polling = (lastVersion != null && lastVersion < new Version(3, 0, 358))
? PollingParameters.Default // Default polling periode was 10s up to 3.0.357. Is 60s for later versions.
: settings.PollingParameters;
AppVersion = currentVersion ?? new Version(3, 0, 122);

View file

@ -673,8 +673,8 @@ namespace TINK.Model
AppResources.ChangeLog3_0_231
},
{
new Version(3, 0, 357),
AppResources.ChangeLog_3_0_357_MK_SB,
new Version(3, 0, 360),
AppResources.ChangeLog_3_0_358_MK_SB,
new List<AppFlavor> { AppFlavor.MeinKonrad, AppFlavor.ShareeBike }
},
};

View file

@ -748,11 +748,12 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to You can only start or end a rent with network reception. Turn on mobile data or wifi and drag the page downward with the finger to refresh the page..
/// Looks up a localized string similar to New functions:&lt;ul&gt;&lt;li&gt;If your device is not connected to the Internet, this is now displayed at the top.&lt;/li&gt;&lt;li&gt;You can now update your bike view by dragging from top to bottom. Especially useful after you reconnect to the Internet.&lt;/li&gt;&lt;/ul&gt;
///&lt;br/&gt;In addition:&lt;ul&gt;&lt;li&gt;Software packages were updated.&lt;/li&gt;&lt;li&gt;Minor bug fixes.&lt;/li&gt;&lt;/ul&gt;.
/// </summary>
public static string ChangeLog_3_0_357_MK_SB {
public static string ChangeLog_3_0_358_MK_SB {
get {
return ResourceManager.GetString("ChangeLog_3_0_357_MK_SB", resourceCulture);
return ResourceManager.GetString("ChangeLog_3_0_358_MK_SB", resourceCulture);
}
}
@ -1592,20 +1593,24 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to Lock is blocked. Please ensure that no obstacle prevents lock from opening and try again..
/// Looks up a localized string similar to Ensure that no obstacle prevents lock from opening and try again..
/// </summary>
public static string ErrorOpenLockBoldBlockedMessage {
public static string ErrorOpenLockBoldIsBlockedMessage {
get {
return ResourceManager.GetString("ErrorOpenLockBoldBlockedMessage", resourceCulture);
return ResourceManager.GetString("ErrorOpenLockBoldIsBlockedMessage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Lock was blocked and might still be. Please ensure that no obstacle prevents lock from opening and try again..
/// Looks up a localized string similar to The lock could not be opened correctly. Please try again.
///
///Attention! Your rental has already started.
///
///If the lock still won&apos;t open, make sure the lock is closed and return the bike. Please report it to the support!.
/// </summary>
public static string ErrorOpenLockBoldWasBlockedMessage {
public static string ErrorOpenLockBoldStatusIsUnknownMessage {
get {
return ResourceManager.GetString("ErrorOpenLockBoldWasBlockedMessage", resourceCulture);
return ResourceManager.GetString("ErrorOpenLockBoldStatusIsUnknownMessage", resourceCulture);
}
}
@ -1630,9 +1635,9 @@ namespace TINK.MultilingualResources {
/// <summary>
/// Looks up a localized string similar to Lock can not be opened!.
/// </summary>
public static string ErrorOpenLockStillOpenTitle {
public static string ErrorOpenLockStillClosedTitle {
get {
return ResourceManager.GetString("ErrorOpenLockStillOpenTitle", resourceCulture);
return ResourceManager.GetString("ErrorOpenLockStillClosedTitle", resourceCulture);
}
}
@ -1958,7 +1963,7 @@ namespace TINK.MultilingualResources {
}
/// <summary>
/// Looks up a localized string similar to No network, data is outdated..
/// Looks up a localized string similar to Pull to refresh..
/// </summary>
public static string MarkingDataIsFromCache {
get {
@ -2192,6 +2197,15 @@ namespace TINK.MultilingualResources {
}
}
/// <summary>
/// Looks up a localized string similar to Oops, there is no internet connection..
/// </summary>
public static string MarkingNoNetworkConnection {
get {
return ResourceManager.GetString("MarkingNoNetworkConnection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bike is ok.
/// </summary>

View file

@ -572,17 +572,8 @@ Fehlerhandling verbessert.</value>
<data name="ChangeLog3_0_235" xml:space="preserve">
<value>Veraltetes Objekt durch aktuelles ersetzt.</value>
</data>
<data name="ErrorOpenLockBoldBlockedMessage" xml:space="preserve">
<value>Schloss ist blockiert. Bitte Ursache von Blockierung beheben und Vorgang wiederholen.</value>
</data>
<data name="ErrorOpenLockBoldWasBlockedMessage" xml:space="preserve">
<value>Schloss war oder ist blockiert. Bitte Ursache von Blockierung beheben und Vorgang wiederholen.</value>
</data>
<data name="ErrorOpenLockTitle" xml:space="preserve">
<value>Fehler beim Schlossöffnen!</value>
</data>
<data name="ErrorOpenLockStillOpenTitle" xml:space="preserve">
<value>Schloss kann nicht geöffnet werden!</value>
<value>Fehler beim Schloss Öffnen!</value>
</data>
<data name="ChangeLog3_0_236" xml:space="preserve">
<value>Anzeige von Stationsnamen statt Nummern.
@ -1115,7 +1106,7 @@ Probieren Sie es aus!</value>
<value>Bluetooth-Kommunikation verbessert.</value>
</data>
<data name="MarkingDataIsFromCache" xml:space="preserve">
<value>Kein Netz, Daten sind veraltet.</value>
<value>Zum Aktualisieren ziehen.</value>
</data>
<data name="MarkingBikesAtStationNoBikesAvailable" xml:space="preserve">
<value>Momentan sind keine Fahrräder an dieser Station verfügbar.</value>
@ -1126,10 +1117,27 @@ Probieren Sie es aus!</value>
<data name="MessageTitleInformation" xml:space="preserve">
<value>Information</value>
</data>
<data name="ChangeLog_3_0_357_MK_SB" xml:space="preserve">
<value>Sie können eine Miete nur bei Netzempfang beginnen oder beenden. Schalten Sie mobile Daten oder WLAN ein und ziehen Sie die Seite mit dem Finger nach unten, um Ihre Ansicht zu aktualisieren.</value>
</data>
<data name="ChangeLog_MinorImprovements" xml:space="preserve">
<value>Kleine Verbesserungen.</value>
</data>
<data name="ErrorOpenLockBoldStatusIsUnknownMessage" xml:space="preserve">
<value>Das Schloss konnte nicht korrekt geöffnet werden. Bitte versuchen Sie es erneut.
Achtung! Ihre Miete hat bereits begonnen.
Wenn sich das Schloss weiterhin nicht öffnen lässt, vergewissern Sie sich, dass das Schloss geschlossen ist und geben Sie das Rad zurück. Bitte melden Sie es dem Support!</value>
</data>
<data name="ErrorOpenLockStillClosedTitle" xml:space="preserve">
<value>Schloss kann nicht geöffnet werden!</value>
</data>
<data name="ErrorOpenLockBoldIsBlockedMessage" xml:space="preserve">
<value>Stellen Sie sicher, dass kein Hindernis das Öffnen des Schlosses verhindert und versuchen Sie es erneut.</value>
</data>
<data name="MarkingNoNetworkConnection" xml:space="preserve">
<value>Ups, es ist keine Internetverbindung vorhanden.</value>
</data>
<data name="ChangeLog_3_0_358_MK_SB" xml:space="preserve">
<value>Neue Funktionen:&lt;ul&gt;&lt;li&gt;Wenn Ihr Gerät nicht mit dem Internet verbunden ist, wird dies nun oben angezeigt.&lt;/li&gt;&lt;li&gt;Sie können jetzt Ihre Fahrradansicht aktualisieren, indem Sie von oben nach unten ziehen. Das ist besonders nützlich, wenn Sie sich wieder mit dem Internet verbunden haben.&lt;/li&gt;&lt;/ul&gt;
&lt;br/&gt;Außerdem:&lt;ul&gt;&lt;li&gt;Software Pakete wurde aktualisiert.&lt;/li&gt;&lt;li&gt;Kleinere Fehlerbehebungen.&lt;/li&gt;&lt;/ul&gt;</value>
</data>
</root>

View file

@ -677,13 +677,17 @@ Error handling improved.</value>
<data name="ChangeLog3_0_235" xml:space="preserve">
<value>Obsolete object replaced with up-to-date one.</value>
</data>
<data name="ErrorOpenLockBoldBlockedMessage" xml:space="preserve">
<value>Lock is blocked. Please ensure that no obstacle prevents lock from opening and try again.</value>
<data name="ErrorOpenLockBoldIsBlockedMessage" xml:space="preserve">
<value>Ensure that no obstacle prevents lock from opening and try again.</value>
</data>
<data name="ErrorOpenLockBoldWasBlockedMessage" xml:space="preserve">
<value>Lock was blocked and might still be. Please ensure that no obstacle prevents lock from opening and try again.</value>
<data name="ErrorOpenLockBoldStatusIsUnknownMessage" xml:space="preserve">
<value>The lock could not be opened correctly. Please try again.
Attention! Your rental has already started.
If the lock still won't open, make sure the lock is closed and return the bike. Please report it to the support!</value>
</data>
<data name="ErrorOpenLockStillOpenTitle" xml:space="preserve">
<data name="ErrorOpenLockStillClosedTitle" xml:space="preserve">
<value>Lock can not be opened!</value>
</data>
<data name="ChangeLog3_0_236" xml:space="preserve">
@ -1205,7 +1209,7 @@ Try it out!</value>
<value>Bluetooth communication improved.</value>
</data>
<data name="MarkingDataIsFromCache" xml:space="preserve">
<value>No network, data is outdated.</value>
<value>Pull to refresh.</value>
</data>
<data name="MarkingBikesAtStationNoBikesAvailable" xml:space="preserve">
<value>There are currently no bicycles available at this station.</value>
@ -1216,10 +1220,14 @@ Try it out!</value>
<data name="MessageTitleInformation" xml:space="preserve">
<value>Information</value>
</data>
<data name="ChangeLog_3_0_357_MK_SB" xml:space="preserve">
<value>You can only start or end a rent with network reception. Turn on mobile data or wifi and drag the page downward with the finger to refresh the page.</value>
<data name="ChangeLog_3_0_358_MK_SB" xml:space="preserve">
<value>New functions:&lt;ul&gt;&lt;li&gt;If your device is not connected to the Internet, this is now displayed at the top.&lt;/li&gt;&lt;li&gt;You can now update your bike view by dragging from top to bottom. Especially useful after you reconnect to the Internet.&lt;/li&gt;&lt;/ul&gt;
&lt;br/&gt;In addition:&lt;ul&gt;&lt;li&gt;Software packages were updated.&lt;/li&gt;&lt;li&gt;Minor bug fixes.&lt;/li&gt;&lt;/ul&gt;</value>
</data>
<data name="ChangeLog_MinorImprovements" xml:space="preserve">
<value>Minor improvements.</value>
</data>
<data name="MarkingNoNetworkConnection" xml:space="preserve">
<value>Oops, there is no internet connection.</value>
</data>
</root>

View file

@ -765,21 +765,9 @@ Fehlerhandling verbessert.</target>
<source>Obsolete object replaced with up-to-date one.</source>
<target state="translated">Veraltetes Objekt durch aktuelles ersetzt.</target>
</trans-unit>
<trans-unit id="ErrorOpenLockBoldBlockedMessage" translate="yes" xml:space="preserve">
<source>Lock is blocked. Please ensure that no obstacle prevents lock from opening and try again.</source>
<target state="translated">Schloss ist blockiert. Bitte Ursache von Blockierung beheben und Vorgang wiederholen.</target>
</trans-unit>
<trans-unit id="ErrorOpenLockBoldWasBlockedMessage" translate="yes" xml:space="preserve">
<source>Lock was blocked and might still be. Please ensure that no obstacle prevents lock from opening and try again.</source>
<target state="translated">Schloss war oder ist blockiert. Bitte Ursache von Blockierung beheben und Vorgang wiederholen.</target>
</trans-unit>
<trans-unit id="ErrorOpenLockTitle" translate="yes" xml:space="preserve">
<source>Error while opening lock!</source>
<target state="translated">Fehler beim Schlossöffnen!</target>
</trans-unit>
<trans-unit id="ErrorOpenLockStillOpenTitle" translate="yes" xml:space="preserve">
<source>Lock can not be opened!</source>
<target state="translated">Schloss kann nicht geöffnet werden!</target>
<target state="translated">Fehler beim Schloss Öffnen!</target>
</trans-unit>
<trans-unit id="ChangeLog3_0_236" translate="yes" xml:space="preserve">
<source>Stations names instead descriptions shown on page title.
@ -1525,8 +1513,8 @@ Probieren Sie es aus!</target>
<target state="translated">Bluetooth-Kommunikation verbessert.</target>
</trans-unit>
<trans-unit id="MarkingDataIsFromCache" translate="yes" xml:space="preserve">
<source>No network, data is outdated.</source>
<target state="translated">Kein Netz, Daten sind veraltet.</target>
<source>Pull to refresh.</source>
<target state="translated">Zum Aktualisieren ziehen.</target>
</trans-unit>
<trans-unit id="MarkingBikesAtStationNoBikesAvailable" translate="yes" xml:space="preserve">
<source>There are currently no bicycles available at this station.</source>
@ -1540,14 +1528,40 @@ Probieren Sie es aus!</target>
<source>Information</source>
<target state="translated">Information</target>
</trans-unit>
<trans-unit id="ChangeLog_3_0_357_MK_SB" translate="yes" xml:space="preserve">
<source>You can only start or end a rent with network reception. Turn on mobile data or wifi and drag the page downward with the finger to refresh the page.</source>
<target state="translated">Sie können eine Miete nur bei Netzempfang beginnen oder beenden. Schalten Sie mobile Daten oder WLAN ein und ziehen Sie die Seite mit dem Finger nach unten, um Ihre Ansicht zu aktualisieren.</target>
</trans-unit>
<trans-unit id="ChangeLog_MinorImprovements" translate="yes" xml:space="preserve">
<source>Minor improvements.</source>
<target state="translated">Kleine Verbesserungen.</target>
</trans-unit>
<trans-unit id="ErrorOpenLockBoldStatusIsUnknownMessage" translate="yes" xml:space="preserve">
<source>The lock could not be opened correctly. Please try again.
Attention! Your rental has already started.
If the lock still won't open, make sure the lock is closed and return the bike. Please report it to the support!</source>
<target state="translated">Das Schloss konnte nicht korrekt geöffnet werden. Bitte versuchen Sie es erneut.
Achtung! Ihre Miete hat bereits begonnen.
Wenn sich das Schloss weiterhin nicht öffnen lässt, vergewissern Sie sich, dass das Schloss geschlossen ist und geben Sie das Rad zurück. Bitte melden Sie es dem Support!</target>
</trans-unit>
<trans-unit id="ErrorOpenLockStillClosedTitle" translate="yes" xml:space="preserve">
<source>Lock can not be opened!</source>
<target state="translated">Schloss kann nicht geöffnet werden!</target>
</trans-unit>
<trans-unit id="ErrorOpenLockBoldIsBlockedMessage" translate="yes" xml:space="preserve">
<source>Ensure that no obstacle prevents lock from opening and try again.</source>
<target state="translated">Stellen Sie sicher, dass kein Hindernis das Öffnen des Schlosses verhindert und versuchen Sie es erneut.</target>
</trans-unit>
<trans-unit id="MarkingNoNetworkConnection" translate="yes" xml:space="preserve">
<source>Oops, there is no internet connection.</source>
<target state="translated">Ups, es ist keine Internetverbindung vorhanden.</target>
</trans-unit>
<trans-unit id="ChangeLog_3_0_358_MK_SB" translate="yes" xml:space="preserve">
<source>New functions:<bpt id="1">&lt;ul&gt;</bpt><bpt id="2">&lt;li&gt;</bpt>If your device is not connected to the Internet, this is now displayed at the top.<ept id="2">&lt;/li&gt;</ept><bpt id="3">&lt;li&gt;</bpt>You can now update your bike view by dragging from top to bottom. Especially useful after you reconnect to the Internet.<ept id="3">&lt;/li&gt;</ept><ept id="1">&lt;/ul&gt;</ept>
&lt;br/&gt;In addition:<bpt id="4">&lt;ul&gt;</bpt><bpt id="5">&lt;li&gt;</bpt>Software packages were updated.<ept id="5">&lt;/li&gt;</ept><bpt id="6">&lt;li&gt;</bpt>Minor bug fixes.<ept id="6">&lt;/li&gt;</ept><ept id="4">&lt;/ul&gt;</ept></source>
<target state="translated">Neue Funktionen:<bpt id="1">&lt;ul&gt;</bpt><bpt id="2">&lt;li&gt;</bpt>Wenn Ihr Gerät nicht mit dem Internet verbunden ist, wird dies nun oben angezeigt.<ept id="2">&lt;/li&gt;</ept><bpt id="3">&lt;li&gt;</bpt>Sie können jetzt Ihre Fahrradansicht aktualisieren, indem Sie von oben nach unten ziehen. Das ist besonders nützlich, wenn Sie sich wieder mit dem Internet verbunden haben.<ept id="3">&lt;/li&gt;</ept><ept id="1">&lt;/ul&gt;</ept>
&lt;br/&gt;Außerdem:<bpt id="4">&lt;ul&gt;</bpt><bpt id="5">&lt;li&gt;</bpt>Software Pakete wurde aktualisiert.<ept id="5">&lt;/li&gt;</ept><bpt id="6">&lt;li&gt;</bpt>Kleinere Fehlerbehebungen.<ept id="6">&lt;/li&gt;</ept><ept id="4">&lt;/ul&gt;</ept></target>
</trans-unit>
</group>
</body>
</file>

View file

@ -26,12 +26,14 @@ namespace TINK.Repository
/// <param name="copriHost">Host to connect to. </param>
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
/// <param name="sessionCookie">Session cookie if user is logged in, null otherwise.</param>
public CopriCallsHttps(
Uri copriHost,
AppContextInfo appContextInfo,
string uiIsoLangugageName,
string sessionCookie = null)
string sessionCookie = null,
ISmartDevice smartDevice = null)
{
m_oCopriHost = copriHost
?? throw new System.Exception($"Can not construct {GetType()}- object. Uri of copri host must not be null.");
@ -41,8 +43,8 @@ namespace TINK.Repository
: throw new System.Exception($"Can not construct {GetType()}- object. User agent must not be null or empty.");
requestBuilder = string.IsNullOrEmpty(sessionCookie)
? new RequestBuilder(appContextInfo.MerchantId, uiIsoLangugageName) as IRequestBuilder
: new RequestBuilderLoggedIn(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie);
? new RequestBuilder(appContextInfo.MerchantId, uiIsoLangugageName, smartDevice) as IRequestBuilder
: new RequestBuilderLoggedIn(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie, smartDevice);
}
/// <summary> Holds the URL for rest calls.</summary>
@ -226,31 +228,27 @@ namespace TINK.Repository
/// <summary> Returns a bike. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="location">Geolocation of lock.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <returns>Response on returning request.</returns>
public async Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto location,
ISmartDevice smartDevice,
Uri operatorUri)
=> await DoReturn(
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
requestBuilder.DoReturn(bikeId, location, smartDevice),
requestBuilder.DoReturn(bikeId, location),
UserAgent);
/// <summary> Returns a bike and starts closing. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <returns>Response on returning request.</returns>
public async Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> await DoReturn(
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
requestBuilder.ReturnAndStartClosing(bikeId, smartDevice),
requestBuilder.ReturnAndStartClosing(bikeId),
UserAgent);
/// <summary> Submits feedback to copri server. </summary>
@ -325,15 +323,15 @@ namespace TINK.Repository
/// <param name="copriHost">Host to connect to. </param>
/// <param name="command">Command to log user out.</param>
public static async Task<AuthorizationoutResponse> DoAuthoutAsync(
string p_strCopriHost,
string p_oCommand,
string copriHost,
string command,
string userAgent = null)
{
#if !WINDOWS_UWP
string l_oLogoutResponse;
string logoutResponse;
try
{
l_oLogoutResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
logoutResponse = await PostAsync(copriHost, command, userAgent);
}
catch (System.Exception l_oException)
@ -352,7 +350,7 @@ namespace TINK.Repository
}
/// Extract session cookie from response.
return CopriCallsStatic.DeserializeResponse<AuthorizationoutResponse>(l_oLogoutResponse, (version) => new UnsupportedCopriVersionDetectedException());
return CopriCallsStatic.DeserializeResponse<AuthorizationoutResponse>(logoutResponse, (version) => new UnsupportedCopriVersionDetectedException());
#else
return null;
#endif
@ -361,19 +359,19 @@ namespace TINK.Repository
/// <summary>
/// Get list of stations from file.
/// </summary>
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
/// <param name="p_oCommand">Command to get stations.</param>
/// <param name="copriHost">URL of the copri host to connect to.</param>
/// <param name="command">Command to get stations.</param>
/// <returns>List of files.</returns>
public static async Task<StationsAvailableResponse> GetStationsAsync(
string p_strCopriHost,
string p_oCommand,
string copriHost,
string command,
string userAgent = null)
{
#if !WINDOWS_UWP
string response;
try
{
response = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
response = await PostAsync(copriHost, command, userAgent);
}
catch (System.Exception l_oException)
{
@ -401,7 +399,7 @@ namespace TINK.Repository
/// <summary> Gets a list of bikes from Copri. </summary>
/// <param name="copriHost">URL of the copri host to connect to.</param>
/// <param name="p_oCommand">Command to get bikes.</param>
/// <param name="command">Command to get bikes.</param>
/// <returns>Response holding list of bikes.</returns>
public static async Task<BikesAvailableResponse> GetBikesAvailableAsync(
string copriHost,
@ -440,19 +438,19 @@ namespace TINK.Repository
}
/// <summary> Gets a list of bikes reserved/ booked by acctive user from Copri.</summary>
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
/// <param name="p_oCommand">Command to post.</param>
/// <param name="copriHost">URL of the copri host to connect to.</param>
/// <param name="command">Command to post.</param>
/// <returns>Response holding list of bikes.</returns>
public static async Task<BikesReservedOccupiedResponse> GetBikesOccupiedAsync(
string p_strCopriHost,
string p_oCommand,
string copriHost,
string command,
string userAgent = null)
{
#if !WINDOWS_UWP
string response;
try
{
response = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
response = await PostAsync(copriHost, command, userAgent);
}
catch (System.Exception l_oException)
{

View file

@ -1296,8 +1296,8 @@ namespace TINK.Repository
SessionCookie = sessionCookie;
requestBuilder = string.IsNullOrEmpty(sessionCookie)
? new RequestBuilder(MerchantId, null /*UI language */) as IRequestBuilder
: new RequestBuilderLoggedIn(MerchantId, null /*UI language */, sessionCookie);
? new RequestBuilder(MerchantId, null /*UI language */, null /* smart device */) as IRequestBuilder
: new RequestBuilderLoggedIn(MerchantId, null /*UI language */, sessionCookie, null /* smart device */);
}
@ -1358,7 +1358,7 @@ namespace TINK.Repository
/// <summary>
/// Get list of stations from file.
/// </summary>
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
/// <param name="cookie">Auto cookie of user if user is logged in.</param>
/// <returns>List of files.</returns>
public async Task<StationsAvailableResponse> GetStationsAsync()
{
@ -1379,7 +1379,7 @@ namespace TINK.Repository
/// Gets canel booking request response.
/// </summary>
/// <param name="bikeId">Id of the bike to book.</param>
/// <param name="p_strCookie">Cookie of the logged in user.</param>
/// <param name="cookie">Cookie of the logged in user.</param>
/// <returns>Response on cancel booking request.</returns>
public async Task<ReservationCancelReturnResponse> DoCancelReservationAsync(string bikeId, Uri operatorUri)
{
@ -1546,14 +1546,14 @@ namespace TINK.Repository
/// <summary>
/// Gets stations response.
/// </summary>
/// <param name="p_strMerchantId">Id of the merchant.</param>
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
/// <param name="merchantId">Id of the merchant.</param>
/// <param name="cookie">Auto cookie of user if user is logged in.</param>
/// <param name="p_eSampleSet"></param>
/// <param name="p_lStageIndex"></param>
/// <returns></returns>
public static StationsAvailableResponse GetStationsAll(
string p_strMerchantId,
string p_strCookie = null,
string merchantId,
string cookie = null,
SampleSets p_eSampleSet = DEFAULT_SAMPLE_SET,
long p_lStageIndex = DEFAULT_STAGE_INDEX)
{
@ -1657,13 +1657,11 @@ namespace TINK.Repository
public Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto geolocation,
ISmartDevice smartDevice,
Uri operatorUri)
=> null;
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> throw new NotImplementedException();

View file

@ -117,20 +117,22 @@ namespace TINK.Repository
public string SessionCookie => requestBuilder.SessionCookie;
/// <summary> Initializes a instance of the copri monkey store object. </summary>
/// <param name="p_strMerchantId">Id of the merchant.</param>
/// <param name="merchantId">Id of the merchant.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="sessionCookie">Session cookie if user is logged in, null otherwise.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
public CopriCallsMonkeyStore(
string merchantId,
string uiIsoLangugageName,
string sessionCookie = null,
ISmartDevice smartDevice = null,
TimeSpan? expiresAfter = null)
{
ExpiresAfter = expiresAfter ?? TimeSpan.FromSeconds(1);
requestBuilder = string.IsNullOrEmpty(sessionCookie)
? new RequestBuilder(merchantId, uiIsoLangugageName) as IRequestBuilder
: new RequestBuilderLoggedIn(merchantId, uiIsoLangugageName, sessionCookie);
? new RequestBuilder(merchantId, uiIsoLangugageName, smartDevice) as IRequestBuilder
: new RequestBuilderLoggedIn(merchantId, uiIsoLangugageName, sessionCookie, smartDevice);
// Ensure that store holds valid entries.
if (!Barrel.Current.Exists(requestBuilder.GetBikesAvailable()))
@ -201,18 +203,15 @@ namespace TINK.Repository
public Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto geolocation,
ISmartDevice smartDevice,
Uri operatorUri)
=> throw new System.Exception("Rückgabe im Offlinemodus nicht möglich!");
/// <summary> Returns a bike and starts closing. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <returns>Response on returning request.</returns>
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> throw new System.Exception("Rückgabe mit Schloss schließen Befehl im Offlinemodus nicht möglich!");

View file

@ -107,13 +107,11 @@ namespace TINK.Repository
/// <summary> Returns a bike. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="location">Geolocation of lock.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <returns>Response on returning request.</returns>
Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto location,
ISmartDevice smartDevice,
Uri operatorUri);
/// <summary> Returns a bike and starts closing. </summary>
@ -123,7 +121,6 @@ namespace TINK.Repository
/// <returns>Response on returning request.</returns>
Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri);
/// <summary>

View file

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Model.Connector;
using TINK.Model.Device;
namespace TINK.Repository.Request
{
@ -26,7 +25,7 @@ namespace TINK.Repository.Request
string deviceId);
/// <summary> Logs user out. </summary>
/// <param name="p_strMerchantId">Id of the merchant.</param>
/// <param name="merchantId">Id of the merchant.</param>
/// <param name="p_strSessionCookie"> Cookie which identifies user.</param>
string DoAuthout();
@ -98,13 +97,13 @@ namespace TINK.Repository.Request
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="location">Geolocation of lock when returning bike.</param>
/// <returns>Requst on returning request.</returns>
string DoReturn(string bikeId, LocationDto location, ISmartDevice smartDevice);
string DoReturn(string bikeId, LocationDto location);
/// <summary> Returns a bike and starts closing. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <returns>Response to send to corpi.</returns>
string ReturnAndStartClosing(string bikeId, ISmartDevice smartDevice);
string ReturnAndStartClosing(string bikeId);
/// <summary>
/// Gets request for submiting feedback to copri server.

View file

@ -14,9 +14,11 @@ namespace TINK.Repository.Request
/// <summary> Constructs a object for building requests. </summary>
/// <param name="merchantId">Holds the id denoting the merchant.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
public RequestBuilder(
string merchantId,
string uiIsoLangugageName)
string uiIsoLangugageName,
ISmartDevice smartDevice = null)
{
MerchantId = !string.IsNullOrEmpty(merchantId)
? merchantId
@ -25,6 +27,8 @@ namespace TINK.Repository.Request
UiIsoLanguageNameParameter = RequestBuilderHelper.GetLanguageParameter(WebUtility.UrlEncode(uiIsoLangugageName));
AuthCookieParameter = $"&authcookie={WebUtility.UrlEncode(MerchantId)}";
SmartDevice = smartDevice;
}
/// <summary>Holds the id denoting the merchant.</summary>
@ -39,6 +43,9 @@ namespace TINK.Repository.Request
/// <summary> Auth cookie parameter. </summary>
private string AuthCookieParameter { get; }
/// <summary>Holds info about smart device.</summary>
private ISmartDevice SmartDevice { get; }
/// <summary> Gets request to log user in. </summary>
/// <param name="mailAddress">Mailaddress of user to log in.</param>
/// <param name="password">Password to log in.</param>
@ -71,6 +78,7 @@ namespace TINK.Repository.Request
public string GetStations()
=> "request=stations_available" +
AuthCookieParameter +
SmartDevice.GetSmartDeviceParameters() +
UiIsoLanguageNameParameter;
/// <summary> Gets a list of bikes reserved/ booked by acctive user from Copri.</summary>
@ -125,14 +133,14 @@ namespace TINK.Repository.Request
public string BookReservedAndStartOpening(string bikeId)
=> throw new NotSupportedException();
public string DoReturn(string bikeId, LocationDto geolocation, ISmartDevice smartDevice)
public string DoReturn(string bikeId, LocationDto geolocation)
=> throw new NotSupportedException();
/// <summary> Returns a bike and starts closing. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <returns>Response to send to corpi.</returns>
public string ReturnAndStartClosing(string bikeId, ISmartDevice smartDevice)
public string ReturnAndStartClosing(string bikeId)
=> throw new NotSupportedException();
/// <summary> Gets submit feedback request. </summary>

View file

@ -1,5 +1,7 @@
using System.Net;
using TINK.Model.Connector;
using TINK.Model.Device;
namespace TINK.Repository.Request
{
@ -29,5 +31,16 @@ namespace TINK.Repository.Request
return null;
}
}
/// <summary> Gets the smart device parameters. </summary>
/// <returns>in a format which is urlencode invariant.</returns>
public static string GetSmartDeviceParameters(this ISmartDevice smartDevice)
=> smartDevice != null
? $"{(!string.IsNullOrEmpty(smartDevice.Manufacturer) ? $"&user_device_manufacturer={WebUtility.UrlEncode(smartDevice.Manufacturer)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Model) ? $"&user_device_model={WebUtility.UrlEncode(smartDevice.Model)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Platform.ToString()) ? $"&user_device_platform={WebUtility.UrlEncode(smartDevice.Platform.ToString())}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.VersionText) ? $"&user_device_version={WebUtility.UrlEncode(smartDevice.VersionText)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Identifier) ? $"&user_device_id={WebUtility.UrlEncode(smartDevice.Identifier)}" : string.Empty)}"
: string.Empty;
}
}

View file

@ -17,10 +17,12 @@ namespace TINK.Repository.Request
/// <summary> Constructs a object for building requests. </summary>
/// <param name="merchantId">Holds the id denoting the merchant.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
public RequestBuilderLoggedIn(
string merchantId,
string uiIsoLangugageName,
string sessionCookie)
string sessionCookie,
ISmartDevice smartDevice = null)
{
MerchantId = !string.IsNullOrEmpty(merchantId)
? merchantId
@ -33,6 +35,8 @@ namespace TINK.Repository.Request
UiIsoLanguageNameParameter = RequestBuilderHelper.GetLanguageParameter(WebUtility.UrlEncode(uiIsoLangugageName));
AuthCookieParameter = $"&authcookie={WebUtility.UrlEncode(SessionCookie)}{WebUtility.UrlEncode(MerchantId)}";
SmartDevice = smartDevice;
}
/// <summary> Holds the id denoting the merchant. </summary>
@ -47,6 +51,9 @@ namespace TINK.Repository.Request
/// <summary> Auth cookie parameter. </summary>
private string AuthCookieParameter { get; }
/// <summary>Holds info about smart device.</summary>
private ISmartDevice SmartDevice { get; }
/// <summary> Gets request to log user in. </summary>
/// <param name="mailAddress">Mailaddress of user to log in.</param>
/// <param name="password">Password to log in.</param>
@ -83,6 +90,7 @@ namespace TINK.Repository.Request
public string GetStations()
=> "request=stations_available" +
AuthCookieParameter +
SmartDevice.GetSmartDeviceParameters() +
UiIsoLanguageNameParameter;
/// <summary> Gets reservation request (synonym: reservation == request == reservieren). </summary>
@ -93,6 +101,7 @@ namespace TINK.Repository.Request
=> "request=booking_request" +
GetBikeIdParameter(bikeId) +
AuthCookieParameter +
SmartDevice.GetSmartDeviceParameters() +
UiIsoLanguageNameParameter;
/// <summary> Gets request to cancel reservation. </summary>
@ -175,6 +184,7 @@ namespace TINK.Repository.Request
AuthCookieParameter +
"&state=occupied" +
GetLockStateParameter(lock_state.unlocking) +
SmartDevice.GetSmartDeviceParameters() +
UiIsoLanguageNameParameter;
/// <summary> Gets the request to book and start opening the bike (synonym: booking == renting == mieten). </summary>
@ -193,14 +203,14 @@ namespace TINK.Repository.Request
/// <param name="bikeId">Id of bike to return.</param>
/// <param name="geolocation">Geolocation of lock when returning bike.</param>
/// <returns>Requst on returning request.</returns>
public string DoReturn(string bikeId, LocationDto geolocation, ISmartDevice smartDevice)
public string DoReturn(string bikeId, LocationDto geolocation)
=> "request=booking_update" +
GetBikeIdParameter(bikeId) +
AuthCookieParameter +
"&state=available" +
GetLocationParameters(geolocation) +
GetLockStateParameter(lock_state.locked) +
GetSmartDeviceParameters(smartDevice) +
SmartDevice.GetSmartDeviceParameters() +
GetLog() +
UiIsoLanguageNameParameter;
@ -209,13 +219,13 @@ namespace TINK.Repository.Request
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <returns>Response to send to corpi.</returns>
public string ReturnAndStartClosing(string bikeId, ISmartDevice smartDevice)
public string ReturnAndStartClosing(string bikeId)
=> "request=booking_update" +
GetBikeIdParameter(bikeId) +
AuthCookieParameter +
"&state=available" +
GetLockStateParameter(lock_state.locking) +
GetSmartDeviceParameters(smartDevice) +
SmartDevice.GetSmartDeviceParameters() +
UiIsoLanguageNameParameter;
/// <summary> Gets submit feedback request. </summary>
@ -315,17 +325,6 @@ namespace TINK.Repository.Request
return $"&gps={geolocation.Latitude.ToString(CultureInfo.InvariantCulture)},{geolocation.Longitude.ToString(CultureInfo.InvariantCulture)}&gps_accuracy={geolocation.Accuracy.Value.ToString(CultureInfo.InvariantCulture)}&gps_age={geolocation.Age.TotalSeconds}";
}
/// <summary> Gets the geolocation parameter. </summary>
/// <returns>in a format which is urlencode invariant.</returns>
private static string GetSmartDeviceParameters(ISmartDevice smartDevice)
=> smartDevice != null
? $"{(!string.IsNullOrEmpty(smartDevice.Manufacturer) ? $"&user_device_manufaturer={WebUtility.UrlEncode(smartDevice.Manufacturer)})" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Model) ? $"&user_device_model={WebUtility.UrlEncode(smartDevice.Model)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Platform.ToString()) ? $"&user_device_platform={WebUtility.UrlEncode(smartDevice.Platform.ToString())}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.VersionText) ? $"&user_device_version={WebUtility.UrlEncode(smartDevice.VersionText)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Identifier) ? $"&user_device_id={WebUtility.UrlEncode(smartDevice.Identifier)}" : string.Empty)}"
: string.Empty;
/// <summary>
/// Gets logging entries from serilog.
/// </summary>

View file

@ -12,7 +12,7 @@ using TINK.Repository.Response;
namespace TINK.Model.Services.CopriApi
{
/// <summary> Object which manages calls to copri in a thread safe way inclding cache functionality. </summary>
/// <summary> Object which manages calls to copri in a thread safe way including cache functionality. </summary>
public class CopriProviderHttps : ICachedCopriServer
{
/// <summary> Object which manages stored copri answers. </summary>
@ -34,6 +34,7 @@ namespace TINK.Model.Services.CopriApi
/// <param name="copriHost"></param>
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
/// <param name="sessionCookie">Cookie of user if a user is logged in, false otherwise.</param>
/// <param name="expiresAfter">Timespan which holds value after which cache expires.</param>
public CopriProviderHttps(
@ -41,13 +42,14 @@ namespace TINK.Model.Services.CopriApi
string merchantId,
AppContextInfo appContextInfo,
string uiIsoLangugageName,
ISmartDevice smartDevice = null,
string sessionCookie = null,
TimeSpan? expiresAfter = null,
ICopriCache cacheServer = null,
ICopriServer httpsServer = null)
{
CacheServer = cacheServer ?? new CopriCallsMonkeyStore(merchantId, uiIsoLangugageName, sessionCookie, expiresAfter);
HttpsServer = httpsServer ?? new CopriCallsHttps(copriHost, appContextInfo, uiIsoLangugageName, sessionCookie);
CacheServer = cacheServer ?? new CopriCallsMonkeyStore(merchantId, uiIsoLangugageName, sessionCookie, smartDevice, expiresAfter);
HttpsServer = httpsServer ?? new CopriCallsHttps(copriHost, appContextInfo, uiIsoLangugageName, sessionCookie, smartDevice);
}
/// <summary>Gets bikes available.</summary>
@ -275,20 +277,17 @@ namespace TINK.Model.Services.CopriApi
public async Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto location,
ISmartDevice smartDevice,
Uri operatorUri)
=> await HttpsServer.DoReturn(bikeId, location, smartDevice, operatorUri);
=> await HttpsServer.DoReturn(bikeId, location, operatorUri);
/// <summary> Returns a bike and starts closing. </summary>
/// <param name="bikeId">Id of the bike to return.</param>
/// <param name="smartDevice">Provides info about hard and software.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <returns>Response on returning request.</returns>
public async Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> await HttpsServer.ReturnAndStartClosingAsync(bikeId, smartDevice, operatorUri);
=> await HttpsServer.ReturnAndStartClosingAsync(bikeId, operatorUri);
/// <summary>
/// Submits feedback to copri server.

View file

@ -11,6 +11,7 @@ using TINK.Services.CopriApi.Exception;
namespace TINK.Model.Services.CopriApi
{
/// <summary> Object which manages calls to cache. </summary>
public class CopriProviderMonkeyStore : ICopriServer
{
/// <summary> Object which manages stored copri answers. </summary>
@ -25,12 +26,14 @@ namespace TINK.Model.Services.CopriApi
/// <summary> Constructs object which Object which manages stored copri answers in a thread save way. </summary>
/// <param name="merchantId">Id of the merchant TINK-App.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
public CopriProviderMonkeyStore(
string merchantId,
string uiIsoLangugageName,
string sessionCookie)
string sessionCookie,
ISmartDevice smartDevice = null)
{
monkeyStore = new CopriCallsMonkeyStore(merchantId, uiIsoLangugageName, sessionCookie);
monkeyStore = new CopriCallsMonkeyStore(merchantId, uiIsoLangugageName, sessionCookie, smartDevice);
}
/// <summary> Gets the merchant id.</summary>
@ -82,15 +85,13 @@ namespace TINK.Model.Services.CopriApi
public async Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto geolocation,
ISmartDevice smartDevice,
Uri operatorUri)
=> await monkeyStore.DoReturn(bikeId, geolocation, smartDevice, operatorUri);
=> await monkeyStore.DoReturn(bikeId, geolocation, operatorUri);
public async Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> await monkeyStore.ReturnAndStartClosingAsync(bikeId, smartDevice, operatorUri);
=> await monkeyStore.ReturnAndStartClosingAsync(bikeId, operatorUri);
public Task<SubmitFeedbackResponse> DoSubmitFeedback(string bikeId, int? currentChargeBars, string messge, bool bIsBikeBroke, Uri operatorUri)
=> throw new RequestNotCachableException(nameof(DoSubmitFeedback));

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
@ -20,18 +20,28 @@ namespace TINK.Services.CopriApi
/// <summary> Timeout for open/ close operations.</summary>
private const int OPEN_CLOSE_TIMEOUT_MS = 50000;
/// <summary> Opens lock.</summary>
/// <param name="copriServer"> Instance to communicate with backend.</param>
/// <param name="bike">Bike object holding id of bike to open. Lock state of object is updated after open request.</param>
public static async Task OpenAync(
this ICopriServerBase copriServer,
IBikeInfoMutable bike)
{
if (!(copriServer is ICachedCopriServer cachedServer))
throw new ArgumentNullException(nameof(copriServer));
await cachedServer.OpenAync(bike);
}
/// <summary> Opens lock.</summary>
/// <param name="corpiServer"> Instance to communicate with backend.</param>
/// <param name="bike">Bike object holding id of bike to open. Lock state of object is updated after open request.</param>
public static async Task OpenAync(
this ICopriServerBase corpiServer,
this ICachedCopriServer cachedServer,
IBikeInfoMutable bike)
{
if (!(corpiServer is ICachedCopriServer cachedServer))
throw new ArgumentNullException(nameof(corpiServer));
// Send command to close lock
await corpiServer.UpdateLockingStateAsync(
await cachedServer.UpdateLockingStateAsync(
bike.Id,
Repository.Request.lock_state.unlocking,
bike.OperatorUri);
@ -169,7 +179,7 @@ namespace TINK.Services.CopriApi
// Send command to open lock
DoReturnResponse response =
await corpiServer.ReturnAndStartClosingAsync(bike.Id, smartDevice, bike.OperatorUri);
await corpiServer.ReturnAndStartClosingAsync(bike.Id, bike.OperatorUri);
// Upate booking state
bike.Load(Model.Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.None);

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="MultilingualAppToolkit">
<MultilingualAppToolkitVersion>4.0</MultilingualAppToolkitVersion>
@ -44,7 +44,7 @@
<PackageReference Include="System.Xml.XDocument" Version="4.3.0" />
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.2.0" />
<PackageReference Include="Xam.Plugins.Messaging" Version="5.2.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.4" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.5" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms.GoogleMaps" Version="5.0.0" />
</ItemGroup>

View file

@ -9,6 +9,9 @@
<!--Secondary color-->
<Color x:Key="secondary-back-title-color">#FF0020</Color>
<!--Attention color-->
<Color x:Key="attention-color">#06D1B1</Color>
<!--Primary Button-->
<Style TargetType="Button">
<Setter Property="WidthRequest" Value="400" />

View file

@ -6,6 +6,9 @@
<!--Main color-->
<Color x:Key="primary-back-title-color">#009899</Color>
<!--Attention color-->
<Color x:Key="attention-color">#FC870D</Color>
<!--Primary Button-->
<Style TargetType="Button">
<Setter Property="WidthRequest" Value="400" />

View file

@ -2,9 +2,11 @@ using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Plugin.Connectivity;
using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.User;
using TINK.MultilingualResources;
using TINK.Services.BluetoothLock;
using TINK.Services.Geolocation;
using TINK.View;
@ -20,6 +22,8 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
/// </summary>
public class BikeViewModel : BikeViewModelBase, INotifyPropertyChanged
{
public Xamarin.Forms.Command ShowTrackingInfoCommand { get; private set; }
/// <summary> Notifies GUI about changes. </summary>
public override event PropertyChangedEventHandler PropertyChanged;
@ -39,12 +43,6 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
string lastStateText = null,
Xamarin.Forms.Color? lastStateColor = null)
{
if (IsDataFromCache != IsDataFromCache)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsDataFromCache)));
}
if (lastHandler.ButtonText != ButtonText)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonText)));
@ -105,6 +103,15 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
IBikesViewModel bikesViewModel,
Action<string> openUrlInBrowser) : base(isConnectedDelegate, connectorFactory, bikeRemoveDelegate, viewUpdateManager, smartDevice, viewService, selectedBike, user, stateInfoProvider, bikesViewModel, openUrlInBrowser)
{
ShowTrackingInfoCommand = new Xamarin.Forms.Command(async () => {
await ViewService.DisplayAlert(
"Tracking",
TariffDescription.TrackingInfoText,
AppResources.MessageAnswerOk);
});
RequestHandler = user.IsLoggedIn
? RequestHandlerFactory.Create(
selectedBike,
@ -132,7 +139,6 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsButtonVisible)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLockitButtonVisible)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsDataFromCache)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OnButtonClicked)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OnLockitButtonClicked)));
};
@ -175,15 +181,13 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
/// <summary> Gets the text of the ILockIt command button. </summary>
public string LockitButtonText => RequestHandler.LockitButtonText;
/// <summary> True if Data is from Cache. </summary>
public bool IsDataFromCache
=> Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Cache;
/// <summary> Processes request to perform a copri action (reserve bike and cancel reservation).
/// Button only enabled if data is up to date = not from cache. </summary>
public System.Windows.Input.ICommand OnButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption1()));
/// <summary> Processes request to perform a copri action (reserve bike and cancel reservation). </summary>
public System.Windows.Input.ICommand OnButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption1()), () => !IsDataFromCache);
/// <summary> Processes request to perform a ILockIt action (unlock bike and lock bike). </summary>
public System.Windows.Input.ICommand OnLockitButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption2()), () => !IsDataFromCache);
/// <summary> Processes request to perform a ILockIt action (unlock bike and lock bike).
/// Button only enabled if data is up to date = not from cache. </summary>
public System.Windows.Input.ICommand OnLockitButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption2()));
/// <summary> Processes request to perform a copri action (reserve bike and cancel reservation). </summary>
private async Task ClickButton(Task<IRequestHandler> handleRequest)

View file

@ -342,16 +342,16 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockTitle,
AppResources.ErrorOpenLockBoldBlockedMessage,
AppResources.ErrorOpenLockBoldIsBlockedMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenBoldWasBlockedException)
else if (exception is CouldntOpenBoldStatusIsUnknownException)
{
Log.ForContext<BookedClosed>().Debug("Lock can not be opened. Bold was or is blocked. {Exception}", exception);
Log.ForContext<BookedClosed>().Debug("Lock can not be opened. Bold status is unknown. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockStillOpenTitle,
AppResources.ErrorOpenLockBoldWasBlockedMessage,
AppResources.ErrorOpenLockStillClosedTitle,
AppResources.ErrorOpenLockBoldStatusIsUnknownMessage,
"OK");
}
else if (exception is CouldntOpenInconsistentStateExecption inconsistentState

View file

@ -94,16 +94,16 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockTitle,
AppResources.ErrorOpenLockBoldBlockedMessage,
AppResources.ErrorOpenLockBoldIsBlockedMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenBoldWasBlockedException)
else if (exception is CouldntOpenBoldStatusIsUnknownException)
{
Log.ForContext<BookedUnknown>().Debug("Lock can not be opened. Bold was or is blocked. {Exception}", exception);
Log.ForContext<BookedUnknown>().Debug("Lock can not be opened. Bold status is unknown. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockStillOpenTitle,
AppResources.ErrorOpenLockBoldWasBlockedMessage,
AppResources.ErrorOpenLockStillClosedTitle,
AppResources.ErrorOpenLockBoldStatusIsUnknownMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenInconsistentStateExecption inconsistentState

View file

@ -283,16 +283,16 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockTitle,
AppResources.ErrorOpenLockBoldBlockedMessage,
AppResources.ErrorOpenLockBoldIsBlockedMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenBoldWasBlockedException)
else if (exception is CouldntOpenBoldStatusIsUnknownException)
{
Log.ForContext<DisposableDisconnected>().Debug("Lock can not be opened. Bold was or is blocked. {Exception}", exception);
Log.ForContext<DisposableDisconnected>().Debug("Lock can not be opened. Bold status is unknown. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockStillOpenTitle,
AppResources.ErrorOpenLockBoldWasBlockedMessage,
AppResources.ErrorOpenLockStillClosedTitle,
AppResources.ErrorOpenLockBoldStatusIsUnknownMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenInconsistentStateExecption inconsistentState

View file

@ -248,16 +248,16 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockTitle,
AppResources.ErrorOpenLockBoldBlockedMessage,
AppResources.ErrorOpenLockBoldIsBlockedMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenBoldWasBlockedException)
else if (exception is CouldntOpenBoldStatusIsUnknownException)
{
Log.ForContext<ReservedClosed>().Debug("Lock can not be opened. Bold was or is blocked. {Exception}", exception);
Log.ForContext<ReservedClosed>().Debug("Lock can not be opened. Bold status is unknown. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockStillOpenTitle,
AppResources.ErrorOpenLockBoldWasBlockedMessage,
AppResources.ErrorOpenLockStillClosedTitle,
AppResources.ErrorOpenLockBoldStatusIsUnknownMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenInconsistentStateExecption inconsistentState

View file

@ -411,16 +411,16 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockTitle,
AppResources.ErrorOpenLockBoldBlockedMessage,
AppResources.ErrorOpenLockBoldIsBlockedMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenBoldWasBlockedException)
else if (exception is CouldntOpenBoldStatusIsUnknownException)
{
Log.ForContext<ReservedDisconnected>().Debug("Lock can not be opened. Bold was or is blocked. {Exception}", exception);
Log.ForContext<ReservedDisconnected>().Debug("Lock can not be opened. Bold status is unknown. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockStillOpenTitle,
AppResources.ErrorOpenLockBoldWasBlockedMessage,
AppResources.ErrorOpenLockStillClosedTitle,
AppResources.ErrorOpenLockBoldStatusIsUnknownMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenInconsistentStateExecption inconsistentState

View file

@ -86,20 +86,20 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
}
else if (exception is CouldntOpenBoldIsBlockedException)
{
Log.ForContext<ReservedUnknown>().Debug("Lock can not be opened. Bold is blocked. {Exception}", exception);
Log.ForContext<ReservedUnknown>().Debug("Lock can not be opened. bold is blocked. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockTitle,
AppResources.ErrorOpenLockBoldBlockedMessage,
AppResources.ErrorOpenLockBoldIsBlockedMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenBoldWasBlockedException)
else if (exception is CouldntOpenBoldStatusIsUnknownException)
{
Log.ForContext<ReservedUnknown>().Debug("Lock can not be opened. Bold was or is blocked. {Exception}", exception);
Log.ForContext<ReservedUnknown>().Debug("Lock can not be opened. lock reports state unkwnown. {Exception}", exception);
await ViewService.DisplayAlert(
AppResources.ErrorOpenLockStillOpenTitle,
AppResources.ErrorOpenLockBoldWasBlockedMessage,
AppResources.ErrorOpenLockStillClosedTitle,
AppResources.ErrorOpenLockBoldStatusIsUnknownMessage,
AppResources.MessageAnswerOk);
}
else if (exception is CouldntOpenInconsistentStateExecption inconsistentState

View file

@ -9,6 +9,8 @@ namespace TINK.ViewModel.Bikes.Bike
/// </summary>
public class TariffDescriptionViewModel
{
private const string TRACKINGKEY = "TRACKING";
public TariffDescriptionViewModel(RentalDescription tariff)
{
Name = tariff?.Name ?? string.Empty;
@ -18,8 +20,13 @@ namespace TINK.ViewModel.Bikes.Bike
: new ObservableCollection<RentalDescription.TariffElement>();
InfoEntries = tariff != null && tariff?.InfoEntries != null
? new ObservableCollection<string>(tariff.InfoEntries.OrderBy(x => x.Key).Select(x => x.Value.Value))
? new ObservableCollection<string>(tariff.InfoEntries
.Where(x => x.Value.Key.ToUpper() != TRACKINGKEY)
.OrderBy(x => x.Key)
.Select(x => x.Value.Value))
: new ObservableCollection<string>();
TrackingInfoText = tariff?.InfoEntries != null ? tariff?.InfoEntries?.FirstOrDefault(x => x.Value.Key.ToUpper() == TRACKINGKEY).Value?.Value ?? string.Empty : string.Empty;
}
/// <summary>
@ -37,11 +44,15 @@ namespace TINK.ViewModel.Bikes.Bike
/// </summary>
public ObservableCollection<string> InfoEntries { get; private set; }
/// <summary>
/// Holds the tracking info text or empty if not applicable.
/// </summary>
public string TrackingInfoText { get; private set; }
public RentalDescription.TariffElement TarifEntry1 => TariffEntries.Count > 0 ? TariffEntries[0] : new RentalDescription.TariffElement();
public RentalDescription.TariffElement TarifEntry2 => TariffEntries.Count > 1 ? TariffEntries[1] : new RentalDescription.TariffElement();
public RentalDescription.TariffElement TarifEntry3 => TariffEntries.Count > 2 ? TariffEntries[2] : new RentalDescription.TariffElement();
public RentalDescription.TariffElement TarifEntry4 => TariffEntries.Count > 3 ? TariffEntries[3] : new RentalDescription.TariffElement();
public RentalDescription.TariffElement TarifEntry5 => TariffEntries.Count > 4 ? TariffEntries[4] : new RentalDescription.TariffElement();
public RentalDescription.TariffElement TarifEntry6 => TariffEntries.Count > 5 ? TariffEntries[5] : new RentalDescription.TariffElement();
public RentalDescription.TariffElement TarifEntry7 => TariffEntries.Count > 6 ? TariffEntries[6] : new RentalDescription.TariffElement();

View file

@ -152,8 +152,6 @@ namespace TINK.ViewModel.Bikes
m_oPolling = polling;
isConnected = IsConnectedDelegate();
OpenUrlInBrowser = openUrlInBrowser;
CollectionChanged += (sender, eventargs) =>
@ -389,11 +387,6 @@ namespace TINK.ViewModel.Bikes
return Exception.GetShortErrorInfoText(IsReportLevelVerbose);
}
if (!IsConnected)
{
return AppResources.ActivityTextConnectionStateOffline;
}
return ActionText ?? string.Empty;
}
}

View file

@ -51,6 +51,9 @@ namespace TINK.ViewModel.BikesAtStation
}
}
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
public Command RefreshCommand { get; }
/// <summary>
@ -92,14 +95,10 @@ namespace TINK.ViewModel.BikesAtStation
? string.Format(AppResources.MarkingBikesAtStationStationId, Station.Id)
: string.Empty;
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
RefreshCommand = new Command(async () => {
IsRefreshing = true;
await OnAppearing();
IsRefreshing = false;
await OnAppearingOrRefresh();
});
@ -242,10 +241,12 @@ namespace TINK.ViewModel.BikesAtStation
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
public async Task OnAppearing()
public async Task OnAppearingOrRefresh()
{
IsIdle = false;
IsConnected = IsConnectedDelegate();
Log.ForContext<BikesAtStationPageViewModel>().Information($"Bikes at station {Station.StationName} is appearing, either due to tap on a station or to app being shown again.");
ActionText = AppResources.ActivityTextOneMomentPlease;
@ -294,7 +295,7 @@ namespace TINK.ViewModel.BikesAtStation
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -316,7 +317,7 @@ namespace TINK.ViewModel.BikesAtStation
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
}
@ -332,7 +333,7 @@ namespace TINK.ViewModel.BikesAtStation
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -360,7 +361,7 @@ namespace TINK.ViewModel.BikesAtStation
// Backup GUI synchronization context.
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
}

View file

@ -299,7 +299,7 @@ namespace TINK.ViewModel.Contact
{
// User decided to give access to locations permissions.
PermissionsService.OpenAppSettings();
ActionText = "";
ActionText = string.Empty;
IsProcessWithRunningProcessView = false;
IsMapPageEnabled = true;
return;
@ -405,7 +405,7 @@ namespace TINK.ViewModel.Contact
Log.ForContext<SelectStationPageViewModel>().Verbose("Update pins color done.");
Exception = resultStationsAndBikes.Exception;
ActionText = "";
ActionText = string.Empty;
IsProcessWithRunningProcessView = false;
IsMapPageEnabled = true;
}
@ -472,12 +472,12 @@ namespace TINK.ViewModel.Contact
await ViewService.ShowPage("//ContactPage");
#endif
IsMapPageEnabled = true;
ActionText = "";
ActionText = string.Empty;
}
catch (Exception exception)
{
IsMapPageEnabled = true;
ActionText = "";
ActionText = string.Empty;
Log.ForContext<SelectStationPageViewModel>().Error("Fehler beim Öffnen der Ansicht \"Fahrräder an Station\" aufgetreten. {Exception}", exception);
await ViewService.DisplayAlert(

View file

@ -25,6 +25,7 @@ using TINK.Services.Permissions;
using TINK.Settings;
using TINK.View;
using TINK.ViewModel.Bikes;
using Xamarin.Essentials;
using Xamarin.Forms;
using Command = Xamarin.Forms.Command;
@ -94,6 +95,9 @@ namespace TINK.ViewModel.FindBike
}
}
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
public Command RefreshCommand { get; }
/// <summary>
@ -136,14 +140,10 @@ namespace TINK.ViewModel.FindBike
Stations = stations ?? throw new ArgumentException(nameof(stations));
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
RefreshCommand = new Command(async () => {
IsRefreshing = true;
await OnAppearing();
IsRefreshing = false;
await SelectBike();
});
}
@ -152,12 +152,17 @@ namespace TINK.ViewModel.FindBike
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
public async Task OnAppearing()
public async Task OnAppearingOrRefresh()
{
IsIdle = false;
Log.ForContext<FindBikePageViewModel>().Information("User request to show page FindBike- page re-appearing");
IsConnected = IsConnectedDelegate();
// Stop polling before getting bikes info.
await m_oViewUpdateManager.StopUpdatePeridically();
if (string.IsNullOrEmpty(BikeIdUserInput) /* Find bike page flyout was taped */
&& BikeCollection.Count > 0 /* Bike was successfully selected */)
{
@ -173,12 +178,12 @@ namespace TINK.ViewModel.FindBike
// Restart update.
await StartUpdateTask(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
}
@ -192,6 +197,8 @@ namespace TINK.ViewModel.FindBike
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
IsIdle = false;
IsConnected = IsConnectedDelegate();
Result<BikeCollection> bikes = null;
try
{
@ -220,7 +227,7 @@ namespace TINK.ViewModel.FindBike
AppResources.MessageAnswerOk);
}
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -241,7 +248,7 @@ namespace TINK.ViewModel.FindBike
string.Format(AppResources.MessageErrorSelectBikeNoBikeFound, BikeIdUserInput),
AppResources.MessageAnswerOk);
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -289,7 +296,7 @@ namespace TINK.ViewModel.FindBike
await StartUpdateTask(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -313,7 +320,7 @@ namespace TINK.ViewModel.FindBike
await StartUpdateTask(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -335,7 +342,7 @@ namespace TINK.ViewModel.FindBike
await StartUpdateTask(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -352,7 +359,7 @@ namespace TINK.ViewModel.FindBike
await StartUpdateTask(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -379,7 +386,7 @@ namespace TINK.ViewModel.FindBike
await StartUpdateTask(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
}
catch (Exception exception)
@ -391,7 +398,7 @@ namespace TINK.ViewModel.FindBike
Log.ForContext<FindBikePageViewModel>().Error("Running command to select bike failed. {Exception}", exception);
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}

View file

@ -26,6 +26,8 @@ using TINK.Services.BluetoothLock;
using TINK.Repository;
using TINK.Services.Geolocation;
using TINK.Model.State;
using TINK.ViewModel.Bikes;
#if !TRYNOTBACKSTYLE
@ -308,7 +310,7 @@ namespace TINK.ViewModel.Map
try
{
//Request Location Permission on iOS
if(DeviceInfo.Platform == DevicePlatform.iOS)
if (DeviceInfo.Platform == DevicePlatform.iOS)
{
var status = await PermissionsService.RequestAsync();
}
@ -336,11 +338,17 @@ namespace TINK.ViewModel.Map
if (!string.IsNullOrEmpty(resultStationsAndBikes?.GeneralData?.MerchantMessage)
&& !WasMerchantMessageAlreadyShown)
{
// Show COPRI message once.
await ViewService.DisplayAlert(
AppResources.MessageTitleInformation,
resultStationsAndBikes.GeneralData.MerchantMessage,
AppResources.MessageAnswerOk);
// Context switch should not be required because code is called from GUI thread
// but a xf-issue requires call (see issue #594).
TinkApp.PostAction( async (x) =>
{
// Show COPRI message once.
await ViewService.DisplayAlert(
AppResources.MessageTitleInformation,
resultStationsAndBikes.GeneralData.MerchantMessage,
AppResources.MessageAnswerOk);
}, null);
WasMerchantMessageAlreadyShown = true;
}
@ -405,7 +413,7 @@ namespace TINK.ViewModel.Map
}
Exception = resultStationsAndBikes.Exception;
ActionText = "";
ActionText = string.Empty;
IsProcessWithRunningProcessView = false;
IsNavBarVisible = true;
IsMapPageEnabled = true;
@ -542,7 +550,7 @@ namespace TINK.ViewModel.Map
{
// User decided to give access to locations permissions.
PermissionsService.OpenAppSettings();
ActionText = "";
ActionText = string.Empty;
IsProcessWithRunningProcessView = false;
IsNavBarVisible = true;
IsMapPageEnabled = true;
@ -655,7 +663,7 @@ namespace TINK.ViewModel.Map
{
try
{
Log.ForContext<MapPageViewModel>().Information($"User taped station {selectedStationId}.");
Log.ForContext<MapPageViewModel>().Information($"User taped station {selectedStationId}.");
// Lock action to prevent multiple instances of "BikeAtStation" being opened.
IsMapPageEnabled = false;
@ -673,13 +681,13 @@ namespace TINK.ViewModel.Map
await ViewService.PushAsync(ViewTypes.BikesAtStation);
IsMapPageEnabled = true;
ActionText = "";
ActionText = string.Empty;
}
}
catch (Exception exception)
{
IsMapPageEnabled = true;
ActionText = "";
ActionText = string.Empty;
Log.ForContext<MapPageViewModel>().Error("Fehler beim Öffnen der Ansicht \"Fahrräder an Station\" aufgetreten. {Exception}", exception);
await ViewService.DisplayAlert(
@ -851,11 +859,6 @@ namespace TINK.ViewModel.Map
return Exception.GetShortErrorInfoText(TinkApp.IsReportLevelVerbose);
}
if (!IsConnected)
{
return AppResources.ActivityTextConnectionStateOffline;
}
return ActionText ?? string.Empty;
}
}
@ -955,7 +958,7 @@ namespace TINK.ViewModel.Map
// Excpetions are handled insde update task;
}
ActionText = "";
ActionText = string.Empty;
IsProcessWithRunningProcessView = false;
IsNavBarVisible = true;
IsMapPageEnabled = true;
@ -964,7 +967,7 @@ namespace TINK.ViewModel.Map
catch (Exception l_oException)
{
Log.ForContext<MapPageViewModel>().Error("An error occurred switching view Cargobike/ Citybike.{}");
ActionText = "";
ActionText = string.Empty;
IsProcessWithRunningProcessView = false;
IsNavBarVisible = true;

View file

@ -22,6 +22,7 @@ using TINK.Services.Permissions;
using TINK.Settings;
using TINK.View;
using TINK.ViewModel.Bikes;
using Xamarin.Essentials;
using Xamarin.Forms;
using Command = Xamarin.Forms.Command;
@ -46,6 +47,11 @@ namespace TINK.ViewModel.MyBikes
}
}
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
public Command RefreshCommand { get; }
/// <summary>
/// Constructs bike collection view model in case information about occupied bikes is available.
/// </summary>
@ -87,20 +93,14 @@ namespace TINK.ViewModel.MyBikes
Stations = stations ?? throw new ArgumentException(nameof(stations));
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
RefreshCommand = new Command(async () => {
IsRefreshing = true;
await OnAppearing();
IsRefreshing = false;
await OnAppearingOrRefresh();
});
}
public Command RefreshCommand { get; }
/// <summary> Returns if info about the fact that user did not request or book any bikes is visible or not.<summary>
/// Gets message that logged in user has not booked any bikes.
/// </summary>
@ -127,15 +127,20 @@ namespace TINK.ViewModel.MyBikes
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
public async Task OnAppearing()
public async Task OnAppearingOrRefresh()
{
IsIdle = false;
IsConnected = IsConnectedDelegate();
// Get my bikes from COPRI
Log.ForContext<MyBikesPageViewModel>().Information("User request to show page MyBikes/ page re-appearing");
ActionText = AppResources.ActivityTextMyBikesLoadingBikes;
// Stop polling before getting bikes info.
await m_oViewUpdateManager.StopUpdatePeridically();
var bikesOccupied = await ConnectorFactory(IsConnected).Query.GetBikesOccupiedAsync();
Exception = bikesOccupied.Exception; // Update communication error from query for bikes occupied.
@ -178,7 +183,7 @@ namespace TINK.ViewModel.MyBikes
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -200,7 +205,7 @@ namespace TINK.ViewModel.MyBikes
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -217,7 +222,7 @@ namespace TINK.ViewModel.MyBikes
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
return;
}
@ -244,7 +249,7 @@ namespace TINK.ViewModel.MyBikes
await OnAppearing(() => UpdateTask());
ActionText = "";
ActionText = string.Empty;
IsIdle = true;
}

View file

@ -130,7 +130,7 @@ namespace TestFramework.Repository
/// <summary>
/// Get list of stations from file.
/// </summary>
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
/// <param name="cookie">Auto cookie of user if user is logged in.</param>
/// <returns>List of files.</returns>
public async Task<StationsAvailableResponse> GetStationsAsync()
=> await Task.Run(() => GetStationsAll(Stations, null, SessionCookie));
@ -147,7 +147,7 @@ namespace TestFramework.Repository
/// Gets canel booking request response.
/// </summary>
/// <param name="bikeId">Id of the bike to book.</param>
/// <param name="p_strCookie">Cookie of the logged in user.</param>
/// <param name="cookie">Cookie of the logged in user.</param>
/// <returns>Response on cancel booking request.</returns>
public async Task<ReservationCancelReturnResponse> DoCancelReservationAsync(string bikeId, Uri operatorUri)
=> await Task.Run(() => DoCancelReservation(CancelBookingRequestResponse, bikeId, SessionCookie));
@ -196,14 +196,14 @@ namespace TestFramework.Repository
/// <summary>
/// Gets list of bikes from memory.
/// </summary>
/// <param name="p_strMerchantId">Id of the merchant.</param>
/// <param name="merchantId">Id of the merchant.</param>
/// <param name="p_strSessionCookie">Auto cookie of user if user is logged in.</param>
/// <param name="p_eSampleSet">Set of samples.</param>
/// <param name="p_lStageIndex">Index of the stage.</param>
/// <returns></returns>
public static BikesAvailableResponse GetBikesAvailable(
string BikesAvailableResponse,
string p_strMerchantId,
string merchantId,
string p_strSessionCookie = null) =>
CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(BikesAvailableResponse);
@ -275,13 +275,11 @@ namespace TestFramework.Repository
public Task<DoReturnResponse> DoReturn(
string bikeId,
LocationDto geolocation,
ISmartDevice smartDevice,
Uri operatorUri)
=> null;
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> null;

View file

@ -74,11 +74,11 @@ namespace TestFramework.Repository
public Task<ReservationBookingResponse> BookReservedAndStartOpeningAsync(string bikeId, Uri operatorUri)
=> throw new NotImplementedException();
public Task<DoReturnResponse> DoReturn(string bikeId, LocationDto location, ISmartDevice smartDevice, Uri operatorUri)
public Task<DoReturnResponse> DoReturn(string bikeId, LocationDto location, Uri operatorUri)
=> throw new NotImplementedException();
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> throw new NotImplementedException();

View file

@ -94,12 +94,11 @@ namespace TestFramework.Services.CopriApi.Connector
public Task<ReservationBookingResponse> BookReservedAndStartOpeningAsync(string bikeId, Uri operatorUri)
=> throw new NotImplementedException();
public Task<DoReturnResponse> DoReturn(string bikeId, LocationDto location, ISmartDevice smartDevice, Uri operatorUri)
public Task<DoReturnResponse> DoReturn(string bikeId, LocationDto location, Uri operatorUri)
=> throw new NotImplementedException();
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
string bikeId,
ISmartDevice smartDevice,
Uri operatorUri)
=> throw new NotImplementedException();

View file

@ -245,7 +245,7 @@ namespace TestLockItBLE
controlCharacteristic.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[] { 0 /* opened */}));
lockControl.GetCharacteristicAsync(new Guid("0000beee-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(activateLock));
activateLock.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true));
stateCharacteristic.Value.Returns(new byte[] { (byte)LockitLockingState.Open /* State passed as event argument after closing. */});
stateCharacteristic.Value.Returns(new byte[] { (byte)LockitLockingState.Unknown /* State passed as event argument after closing. */}); /* changed from .Open to .Unknown (20.02.23, AMM) after bug fix #657. */
// Use factory to create LockIt-object.
var lockIt = LockItEventBased.Authenticate(device, authTdo, adapter, cipher).Result;
@ -294,7 +294,8 @@ namespace TestLockItBLE
// Calls related to Close functionality.
lockControl.GetCharacteristicAsync(new Guid("0000baaa-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(controlCharacteristic));
controlCharacteristic.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[] { 0 /* open */}));
controlCharacteristic.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[] { 0 /* open */
}));
lockControl.GetCharacteristicAsync(new Guid("0000beee-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(activateLock));
activateLock.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true));
stateCharacteristic.Value.Returns(new byte[] { (byte)LockitLockingState.CouldntCloseBoldBlocked /* State passed as event argument after opening. */});
@ -312,4 +313,4 @@ namespace TestLockItBLE
Throws.InstanceOf<CouldntCloseBoldBlockedException>());
}
}
}
}

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
@ -10,10 +10,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NSubstitute" Version="4.4.0" />
<PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
</ItemGroup>
<ItemGroup>

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