Code updated to 3.0.238
|
@ -6,8 +6,8 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Plugin.BLE" Version="2.1.1" />
|
||||
<PackageReference Include="Polly" Version="7.2.1" />
|
||||
<PackageReference Include="Plugin.BLE" Version="2.1.2" />
|
||||
<PackageReference Include="Polly" Version="7.2.2" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Xamarin.Essentials" Version="1.6.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -141,13 +141,17 @@ namespace TINK.Services.BluetoothLock.BLE
|
|||
|
||||
switch (lockingState.Value)
|
||||
{
|
||||
case LockitLockingState.CouldntOpenBoldBlocked:
|
||||
// Expected error. ILockIt count not be opened (Spoke blocks lock, ....)
|
||||
throw new CouldntOpenBoldBlockedException();
|
||||
|
||||
case LockitLockingState.Open:
|
||||
return lockingState.Value;
|
||||
|
||||
case LockitLockingState.CouldntOpenBoldBlocked:
|
||||
// Expected error. ILockIt count not be opened (Spoke blocks lock, ....)
|
||||
throw new CouldntOpenBoldIsBlockedException();
|
||||
|
||||
case LockitLockingState.Unknown:
|
||||
// Expected error. ILockIt count not be opened (Spoke has blocked/ blocks lock, ....)
|
||||
throw new CouldntOpenBoldWasBlockedException();
|
||||
|
||||
default:
|
||||
// Comprises values
|
||||
// - LockitLockingState.Closed
|
||||
|
|
|
@ -109,18 +109,22 @@ namespace TINK.Services.BluetoothLock.BLE
|
|||
|
||||
switch (info.State.Value)
|
||||
{
|
||||
case LockitLockingState.CouldntOpenBoldBlocked:
|
||||
// Expected error. ILockIt count not be opened (Spoke blocks lock, ....)
|
||||
throw new CouldntOpenBoldBlockedException();
|
||||
|
||||
case LockitLockingState.Open:
|
||||
return info.State.Value;
|
||||
|
||||
case LockitLockingState.CouldntOpenBoldBlocked:
|
||||
// Expected error. ILockIt count not be opened (Spoke blocks lock, ....)
|
||||
throw new CouldntOpenBoldIsBlockedException();
|
||||
|
||||
case LockitLockingState.Unknown:
|
||||
// Expected error. ILockIt count not be opened (Spoke has blocked/ blocks lock, ....)
|
||||
throw new CouldntOpenBoldWasBlockedException();
|
||||
|
||||
default:
|
||||
// Comprises values
|
||||
// - LockitLockingState.Closed
|
||||
// - LockitLockingState.Unknown
|
||||
// - LockitLockingState.CouldntOpenBoldBlocked
|
||||
// - LockitLockingState.CouldntCloseMoving (should never happen because command open was send)
|
||||
// - LockitLockingState.CouldntCloseBoldBlocked (should never happen because command open was send)
|
||||
// Internal error which sould never occure. Lock refuses to open but connection is ok.
|
||||
throw new CouldntOpenInconsistentStateExecption(info.State.Value.GetLockingState());
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<Folder Include="Services\BluetoothLock\Tdo\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
<source>Unexpected locking state "{0}" detected after sending open command.</source>
|
||||
<target state="translated">Unerwarteter Schlosszustand "{0}" gemeldet nach Ausführen des Öffnen-Befehls.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ErrorOpenLockUnknownPosition" translate="yes" xml:space="preserve">
|
||||
<source>Lock reports unknown bold position.</source>
|
||||
<target state="needs-review-translation">Schloss meldet unbekannten Schließzustand.</target>
|
||||
<note from="MultilingualUpdate" annotates="source" priority="2">Please verify the translation’s accuracy as the source string was updated after it was translated.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="ErrorBluetoothDisconnectedException" translate="yes" xml:space="preserve">
|
||||
<source>No bluetooth connection.</source>
|
||||
<target state="translated">Keine Bluetooth-Verbindung.</target>
|
||||
|
@ -39,6 +34,10 @@
|
|||
<source>Bold is blocked.</source>
|
||||
<target state="translated">Schloss ist blockiert.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ErrorOpenLockBoldWasBlocked" translate="yes" xml:space="preserve">
|
||||
<source>Bolds was or is blocked.</source>
|
||||
<target state="new">Bolds was or is blocked.</target>
|
||||
</trans-unit>
|
||||
</group>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -114,6 +114,15 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bolds was or is blocked..
|
||||
/// </summary>
|
||||
internal static string ErrorOpenLockBoldWasBlocked {
|
||||
get {
|
||||
return ResourceManager.GetString("ErrorOpenLockBoldWasBlocked", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unexpected locking state "{0}" detected after sending open command..
|
||||
/// </summary>
|
||||
|
@ -122,14 +131,5 @@ namespace TINK.MultilingualResources {
|
|||
return ResourceManager.GetString("ErrorOpenLockUnexpectedState", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Lock reports unknown bold position..
|
||||
/// </summary>
|
||||
internal static string ErrorOpenLockUnknownPosition {
|
||||
get {
|
||||
return ResourceManager.GetString("ErrorOpenLockUnknownPosition", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
<data name="ErrorOpenLockUnexpectedState" xml:space="preserve">
|
||||
<value>Unerwarteter Schlosszustand "{0}" gemeldet nach Ausführen des Öffnen-Befehls.</value>
|
||||
</data>
|
||||
<data name="ErrorOpenLockUnknownPosition" xml:space="preserve">
|
||||
<value>Schloss meldet unbekannten Schließzustand.</value>
|
||||
</data>
|
||||
<data name="ErrorBluetoothDisconnectedException" xml:space="preserve">
|
||||
<value>Keine Bluetooth-Verbindung.</value>
|
||||
</data>
|
||||
|
|
|
@ -135,10 +135,10 @@
|
|||
<data name="ErrorOpenLockBoldBlocked" xml:space="preserve">
|
||||
<value>Bold is blocked.</value>
|
||||
</data>
|
||||
<data name="ErrorOpenLockBoldWasBlocked" xml:space="preserve">
|
||||
<value>Bolds was or is blocked.</value>
|
||||
</data>
|
||||
<data name="ErrorOpenLockUnexpectedState" xml:space="preserve">
|
||||
<value>Unexpected locking state "{0}" detected after sending open command.</value>
|
||||
</data>
|
||||
<data name="ErrorOpenLockUnknownPosition" xml:space="preserve">
|
||||
<value>Lock reports unknown bold position.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,13 +0,0 @@
|
|||
using TINK.Model.Bike.BluetoothLock;
|
||||
|
||||
namespace TINK.Services.BluetoothLock.Exception
|
||||
{
|
||||
public class CouldntOpenBoldBlockedException : StateAwareException
|
||||
{
|
||||
public CouldntOpenBoldBlockedException() : base(
|
||||
LockingState.Unknown, //
|
||||
MultilingualResources.Resources.ErrorOpenLockBoldBlocked)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using TINK.Model.Bike.BluetoothLock;
|
||||
|
||||
namespace TINK.Services.BluetoothLock.Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Lock can not be opened, because bold is blocked. Lock reports that obstacle is still blocking.
|
||||
/// </summary>
|
||||
public class CouldntOpenBoldIsBlockedException : StateAwareException
|
||||
{
|
||||
public CouldntOpenBoldIsBlockedException() : base(
|
||||
LockingState.Unknown,
|
||||
MultilingualResources.Resources.ErrorOpenLockBoldBlocked)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using TINK.Model.Bike.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 CouldntOpenBoldWasBlockedException() : base(
|
||||
LockingState.Unknown,
|
||||
MultilingualResources.Resources.ErrorOpenLockBoldWasBlocked)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,9 +9,7 @@ namespace TINK.Services.BluetoothLock.Exception
|
|||
public CouldntOpenInconsistentStateExecption(LockingState state) :
|
||||
base(
|
||||
state,
|
||||
state != LockingState.Unknown
|
||||
? string.Format(Resources.ErrorOpenLockUnexpectedState, state)
|
||||
: Resources.ErrorOpenLockUnknownPosition)
|
||||
string.Format(Resources.ErrorOpenLockUnexpectedState, state))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,71 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30011.22
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Sharee", "TINK\TINK\Sharee.shproj", "{5297504F-603F-4E1A-98AA-57C4A0D9D833}"
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TINK", "TINK\TINK\TINK.shproj", "{5297504F-603F-4E1A-98AA-57C4A0D9D833}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharee.Android", "TINK\TINK.Android\Sharee.Android.csproj", "{62B8950A-70B8-4F9D-AFFC-0A1EBE7BC9E7}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TINK.Android", "TINK\TINK.Android\TINK.Android.csproj", "{62B8950A-70B8-4F9D-AFFC-0A1EBE7BC9E7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharee.iOS", "TINK\TINK.iOS\Sharee.iOS.csproj", "{F2D8208F-A8BF-4403-B0AE-2A1D270E4DC9}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TINK.iOS", "TINK\TINK.iOS\TINK.iOS.csproj", "{F2D8208F-A8BF-4403-B0AE-2A1D270E4DC9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TINKLib", "TINKLib\TINKLib.csproj", "{B77F4222-0860-4494-A07C-EE8E09FA9983}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{49C8F824-4752-449E-A53C-35A2722AFA99}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Set02 - Book 3rd bike", "Set02 - Book 3rd bike", "{50D4A63A-91D8-4EC5-ADF6-9EF72D7AFAF0}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set02\Story.json = TestData\Set02\Story.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "001", "001", "{A5D8D93B-4D4E-4C4C-A70C-44A451D6C722}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set02\001\bikes_available.json = TestData\Set02\001\bikes_available.json
|
||||
TestData\Set02\001\booking_request_bike_8.json = TestData\Set02\001\booking_request_bike_8.json
|
||||
TestData\Set02\001\stations_all.json = TestData\Set02\001\stations_all.json
|
||||
TestData\Set02\001\user_bikes_occupied.json = TestData\Set02\001\user_bikes_occupied.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "002", "002", "{D0A2A88B-5DD9-4B40-A8AE-2AED6FB41911}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set02\002\bikes_available.json = TestData\Set02\002\bikes_available.json
|
||||
TestData\Set02\002\stations_all.json = TestData\Set02\002\stations_all.json
|
||||
TestData\Set02\002\user_bikes_occupied.json = TestData\Set02\002\user_bikes_occupied.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "003", "003", "{272FB1A5-BBC5-41DF-91C2-C1C1A85AFD44}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set02\003\bikes_available.json = TestData\Set02\003\bikes_available.json
|
||||
TestData\Set02\003\stations_all.json = TestData\Set02\003\stations_all.json
|
||||
TestData\Set02\003\user_bikes_occupied.json = TestData\Set02\003\user_bikes_occupied.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Set03 - Book 1st bike", "Set03 - Book 1st bike", "{E5E0E87A-1CDD-4E66-AF66-26EBDD0C6E61}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set03\Story.json = TestData\Set03\Story.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "001", "001", "{B0BE116C-B05C-4864-9D1F-5CE1A8EC7BD0}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set03\001\booking_request_bike_20.json = TestData\Set03\001\booking_request_bike_20.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "002", "002", "{C579CA91-17DC-4AC4-8F1B-377A245883FD}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Set01 - Log in", "Set01 - Log in", "{A872956F-17F0-416E-9A9A-F28D96F13A94}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "001", "001", "{104F18F2-1261-42C0-96A4-F5BBACF595DA}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set01\001\authorization_javaminister%40gmail.com_javaminister_HwId1000000000000.json = TestData\Set01\001\authorization_javaminister%40gmail.com_javaminister_HwId1000000000000.json
|
||||
TestData\Set01\001\bikes_available.json = TestData\Set01\001\bikes_available.json
|
||||
TestData\Set01\001\bikes_occupied.json = TestData\Set01\001\bikes_occupied.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Set04 - Cancel Booking", "Set04 - Cancel Booking", "{55C5EF2A-FDEB-40F6-ABE9-84B7B1981B2B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "001", "001", "{AADA3B61-8626-43AE-BED9-BA5AA3D93576}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
TestData\Set04 - Cancel Booking\001\booking_cancel_bike_7.json = TestData\Set04 - Cancel Booking\001\booking_cancel_bike_7.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItShared", "LockItShared\LockItShared.csproj", "{3589ED1D-E734-429D-976F-1BEA4371DF14}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItBLE", "LockItBLE\LockItBLE.csproj", "{BDE9CE26-15CF-47DA-A4F6-B6956D02D0FC}"
|
||||
|
@ -451,6 +508,19 @@ Global
|
|||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{50D4A63A-91D8-4EC5-ADF6-9EF72D7AFAF0} = {49C8F824-4752-449E-A53C-35A2722AFA99}
|
||||
{A5D8D93B-4D4E-4C4C-A70C-44A451D6C722} = {50D4A63A-91D8-4EC5-ADF6-9EF72D7AFAF0}
|
||||
{D0A2A88B-5DD9-4B40-A8AE-2AED6FB41911} = {50D4A63A-91D8-4EC5-ADF6-9EF72D7AFAF0}
|
||||
{272FB1A5-BBC5-41DF-91C2-C1C1A85AFD44} = {50D4A63A-91D8-4EC5-ADF6-9EF72D7AFAF0}
|
||||
{E5E0E87A-1CDD-4E66-AF66-26EBDD0C6E61} = {49C8F824-4752-449E-A53C-35A2722AFA99}
|
||||
{B0BE116C-B05C-4864-9D1F-5CE1A8EC7BD0} = {E5E0E87A-1CDD-4E66-AF66-26EBDD0C6E61}
|
||||
{C579CA91-17DC-4AC4-8F1B-377A245883FD} = {E5E0E87A-1CDD-4E66-AF66-26EBDD0C6E61}
|
||||
{A872956F-17F0-416E-9A9A-F28D96F13A94} = {49C8F824-4752-449E-A53C-35A2722AFA99}
|
||||
{104F18F2-1261-42C0-96A4-F5BBACF595DA} = {A872956F-17F0-416E-9A9A-F28D96F13A94}
|
||||
{55C5EF2A-FDEB-40F6-ABE9-84B7B1981B2B} = {49C8F824-4752-449E-A53C-35A2722AFA99}
|
||||
{AADA3B61-8626-43AE-BED9-BA5AA3D93576} = {55C5EF2A-FDEB-40F6-ABE9-84B7B1981B2B}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C6529CD7-C3F7-4E80-89B5-002E2B8E3EB5}
|
||||
EndGlobalSection
|
|
@ -1,16 +1,23 @@
|
|||
using TINK.Model.Device;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
[assembly: Dependency(typeof(TINK.Droid.Model.Device.Device))]
|
||||
namespace TINK.Droid.Model.Device
|
||||
{
|
||||
public class Device : IDevice
|
||||
public class Device : ISmartDevice
|
||||
{
|
||||
public string Manufacturer => DeviceInfo.Manufacturer;
|
||||
|
||||
public string Model => DeviceInfo.Model;
|
||||
|
||||
public string PlatformText => DeviceInfo.Platform.ToString();
|
||||
|
||||
public string VersionText => DeviceInfo.VersionString;
|
||||
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string GetIdentifier()
|
||||
{
|
||||
return Android.Provider.Settings.Secure.GetString(Forms.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
|
||||
}
|
||||
public string Identifier
|
||||
=> Android.Provider.Settings.Secure.GetString(Forms.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.hauffware.sharee" android:versionName="3.0.222" android:versionCode="222">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.hauffware.sharee" android:versionName="3.0.238" android:versionCode="238">
|
||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="30" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<permission android:name="com.ecs.google.maps.v2.actionbarsherlock.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
|
||||
|
@ -15,6 +15,6 @@
|
|||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
|
||||
<application android:icon="@drawable/sharee" android:label="sharee.bike"></application>
|
||||
<application android:icon="@drawable/sharee" android:label="sharee.bike" android:allowBackup="false"></application>
|
||||
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="000000000-000000000000000000000000000-0" />
|
||||
</manifest>
|
20
TINK/TINK.Android/Properties/AndroidManifest.xml.bak
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.hauffware.sharee" android:versionName="3.0.222" android:versionCode="222">
|
||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="30" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<permission android:name="com.ecs.google.maps.v2.actionbarsherlock.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
|
||||
<!-- Network connectivity permissions -->
|
||||
<!-- Access Google based webservices -->
|
||||
<!-- External storage for caching. -->
|
||||
<!-- My Location -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-feature android:name="android.hardware.location" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.location.network" android:required="false" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
|
||||
<application android:icon="@drawable/sharee" android:label="sharee.bike"></application>
|
||||
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="000000000-000000000000000000000000000-0" />
|
||||
</manifest>
|
1785
TINK/TINK.Android/Resources/Resource.Designer.cs
generated
|
@ -30,7 +30,7 @@
|
|||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;USESHELL</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;USEFLYOUT</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>0</WarningLevel>
|
||||
<AndroidUseSharedRuntime>true</AndroidUseSharedRuntime>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DefineConstants>TRACE;USEFLYOUT</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
|
||||
|
@ -63,16 +63,16 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.NETCore.Platforms" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.NETCore.Platforms" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="MonkeyCache">
|
||||
<Version>1.3.0</Version>
|
||||
<Version>1.5.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MonkeyCache.FileStore">
|
||||
<Version>1.3.0</Version>
|
||||
<Version>1.5.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="PCLCrypto" Version="2.0.147" />
|
||||
<PackageReference Include="PCLStorage" Version="1.0.2" />
|
||||
<PackageReference Include="PInvoke.BCrypt" Version="0.7.104" />
|
||||
|
@ -161,11 +161,17 @@
|
|||
<PackageReference Include="Xamarin.Android.Support.v7.Palette" Version="28.0.0.3" />
|
||||
<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.5.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
|
||||
<Version>1.2.1</Version>
|
||||
<Version>1.2.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.Palette">
|
||||
<Version>1.0.0.6</Version>
|
||||
<Version>1.0.0.7</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
|
||||
<Version>1.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
|
||||
<PackageReference Include="Xamarin.Build.Download" Version="0.10.0" />
|
||||
|
@ -182,7 +188,7 @@
|
|||
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="2.2.0" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="117.6.0" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="117.6.0" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="117.0.0" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="117.0.1" />
|
||||
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="117.2.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
|
@ -1,8 +0,0 @@
|
|||
<Application
|
||||
x:Class="TINK.UWP.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TINK.UWP"
|
||||
RequestedTheme="Light">
|
||||
|
||||
</Application>
|
|
@ -1,107 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace TINK.UWP
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
sealed partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += OnSuspending;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
this.DebugSettings.EnableFrameRateCounter = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||
|
||||
Xamarin.Forms.Forms.Init(e);
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
//TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
if (rootFrame.Content == null)
|
||||
{
|
||||
// When the navigation stack isn't restored navigate to the first page,
|
||||
// configuring the new page by passing required information as a navigation
|
||||
// parameter
|
||||
rootFrame.Navigate(typeof(MainPage), e.Arguments);
|
||||
}
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
/// <param name="sender">The Frame which failed navigation</param>
|
||||
/// <param name="e">Details about the navigation failure</param>
|
||||
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when application execution is being suspended. Application state is saved
|
||||
/// without knowing whether the application will be terminated or resumed with the contents
|
||||
/// of memory still intact.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
//TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 305 B |
Before Width: | Height: | Size: 347 B |
Before Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 758 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 394 B |
Before Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 392 B |
Before Width: | Height: | Size: 921 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.7 KiB |
|
@ -1,32 +0,0 @@
|
|||
using System;
|
||||
using TINK.Model.Device;
|
||||
using TINK.UWP.Device;
|
||||
using Windows.System.Profile;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
[assembly: Xamarin.Forms.Dependency(typeof(WinPhoneDevice))]
|
||||
namespace TINK.UWP.Device
|
||||
{
|
||||
public class WinPhoneDevice : IDevice
|
||||
{
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string GetIdentifier()
|
||||
{
|
||||
var token = HardwareIdentification.GetPackageSpecificToken(null);
|
||||
var hardwareId = token.Id;
|
||||
var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);
|
||||
|
||||
byte[] bytes = new byte[hardwareId.Length];
|
||||
dataReader.ReadBytes(bytes);
|
||||
|
||||
return BitConverter.ToString(bytes);
|
||||
}
|
||||
|
||||
/// <summary> Close the application. </summary>
|
||||
public void CloseApplication()
|
||||
{
|
||||
Application.Current.Exit();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<forms:WindowsPage
|
||||
x:Class="TINK.UWP.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:forms="using:Xamarin.Forms.Platform.UWP"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:TINK.UWP"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
</Grid>
|
||||
</forms:WindowsPage>
|
|
@ -1,19 +0,0 @@
|
|||
namespace TINK.UWP
|
||||
{
|
||||
public sealed partial class MainPage
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
// Todo: Token hier eingeben
|
||||
// Required for initialization of Maps, see https://developer.xamarin.com/guides/xamarin-forms/user-interface/map/
|
||||
Xamarin.FormsGoogleMaps.Init("AIzaSyDOd-_356QgShjVGUPGH1LatYJKWdzk9-U");
|
||||
|
||||
// Required for initialization of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
|
||||
Xamarin.FormsGoogleMapsBindings.Init();
|
||||
|
||||
LoadApplication(new TINK.App());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity
|
||||
Name="4fa9c991-fff2-493e-b399-75bf6354090c"
|
||||
Publisher="CN=Oliver"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="f736c883-f105-4d30-a719-4bf328872f5e" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>TINK.UWP</DisplayName>
|
||||
<PublisherDisplayName>Oliver</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="TINK.UWP.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="TINK.UWP"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||
Description="TINK.UWP"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -1,29 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("TINK.UWP")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("TINK.UWP")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
|
@ -1,31 +0,0 @@
|
|||
<!--
|
||||
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||
optimizer.
|
||||
|
||||
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
|
||||
|
||||
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||
|
||||
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||
|
||||
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
|
||||
-->
|
||||
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<!--
|
||||
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||
the application package. The asterisks are not wildcards.
|
||||
-->
|
||||
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||
|
||||
|
||||
<!-- Add your application specific runtime directives here. -->
|
||||
|
||||
|
||||
</Application>
|
||||
</Directives>
|
|
@ -1,171 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{B3DC74E1-DA60-4844-BB25-A7F6D2BB6A9D}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TINK.UWP</RootNamespace>
|
||||
<AssemblyName>TINK.UWP</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.15063.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10586.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>TINK.UWP_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<ReleaseVersion>3.0</ReleaseVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Device\WinPhoneDevice .cs" />
|
||||
<Compile Include="MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<None Include="TINK.UWP_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\tink2.png" />
|
||||
<Content Include="Properties\Default.rd.xml" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-100.png" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-125.png" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-150.png" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-400.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-100.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-125.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-150.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-400.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-100.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-125.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-150.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-400.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-16_altform-unplated.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-32_altform-unplated.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-48_altform-unplated.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-256_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-100.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-125.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-150.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-400.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\TINKLib\TINKLib.csproj">
|
||||
<Project>{b77f4222-0860-4494-a07c-ee8e09fa9983}</Project>
|
||||
<Name>TINKLib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\TINK\TINK.projitems" Label="Shared" Condition="Exists('..\TINK\TINK.projitems')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.Net.Http": "2.2.29",
|
||||
"Microsoft.NETCore.UniversalWindowsPlatform": "6.1.4",
|
||||
"PCLStorage": "1.0.2",
|
||||
"Serilog": "2.7.1",
|
||||
"Serilog.Sinks.File": "4.0.0",
|
||||
"System.Collections.Immutable": "1.4.0",
|
||||
"System.Private.DataContractSerialization": "4.3.0",
|
||||
"System.Runtime.Serialization.Formatters": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0",
|
||||
"Xam.Plugins.Messaging": "5.2.0",
|
||||
"Xamarin.Forms": "3.0.0.482510",
|
||||
"Xamarin.Forms.GoogleMaps": "2.3.0",
|
||||
"Xamarin.Forms.GoogleMaps.Bindings": "2.1.0"
|
||||
},
|
||||
"frameworks": {
|
||||
"uap10.0.10586": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win10-arm": {},
|
||||
"win10-arm-aot": {},
|
||||
"win10-x86": {},
|
||||
"win10-x86-aot": {},
|
||||
"win10-x64": {},
|
||||
"win10-x64-aot": {}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using TINK.Model.Device;
|
||||
using Xamarin.Essentials;
|
||||
|
||||
[assembly: Xamarin.Forms.Dependency(typeof(TINK.iOS.Device.Device))]
|
||||
namespace TINK.iOS.Device
|
||||
{
|
||||
public class Device : IDevice
|
||||
public class Device : ISmartDevice
|
||||
{
|
||||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);
|
||||
|
@ -19,11 +20,16 @@ namespace TINK.iOS.Device
|
|||
[DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
|
||||
private static extern int IOObjectRelease(uint o);
|
||||
|
||||
public string Manufacturer => DeviceInfo.Manufacturer;
|
||||
|
||||
public string Model => DeviceInfo.Model;
|
||||
|
||||
public string PlatformText => DeviceInfo.Platform.ToString();
|
||||
|
||||
public string VersionText => DeviceInfo.VersionString;
|
||||
/// <summary> Gets unitque device identifier. </summary>
|
||||
/// <returns>Gets the identifies specifying device.</returns>
|
||||
public string GetIdentifier()
|
||||
{
|
||||
return UIKit.UIDevice.CurrentDevice?.IdentifierForVendor?.AsString() ?? string.Empty;
|
||||
}
|
||||
public string Identifier
|
||||
=> UIKit.UIDevice.CurrentDevice?.IdentifierForVendor?.AsString() ?? string.Empty;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)com.TeilRad.sharee.bike</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>sharee.bike</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>222</string>
|
||||
<string>238</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.222</string>
|
||||
<string>3.0.238</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\iPhone\Debug</OutputPath>
|
||||
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;DEBUG;SHOWAGBV1;USEBROWSERFORUSERMANAGEMENT</DefineConstants>
|
||||
<DefineConstants>DEBUG;USEFLYOUT</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>false</ConsolePause>
|
||||
|
@ -61,7 +61,7 @@
|
|||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\iPhone\Release</OutputPath>
|
||||
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;SHOWAGBV1;USEBROWSERFORUSERMANAGEMENT</DefineConstants>
|
||||
<DefineConstants>USEFLYOUT</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<MtouchArch>ARMv7, ARM64</MtouchArch>
|
||||
|
@ -78,7 +78,7 @@
|
|||
<DebugType>none</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
|
||||
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;SHOWAGBV1;USEBROWSERFORUSERMANAGEMENT</DefineConstants>
|
||||
<DefineConstants>USEFLYOUT</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>False</ConsolePause>
|
||||
|
@ -94,7 +94,7 @@
|
|||
<DebugType>none</DebugType>
|
||||
<Optimize>True</Optimize>
|
||||
<OutputPath>bin\iPhone\AppStore</OutputPath>
|
||||
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;SHOWAGBV1;USEBROWSERFORUSERMANAGEMENT</DefineConstants>
|
||||
<DefineConstants>USEFLYOUT</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ConsolePause>False</ConsolePause>
|
||||
|
@ -109,16 +109,16 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Bcl.Build" Version="1.0.21" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.NETCore.Platforms" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.NETCore.Platforms" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="MonkeyCache">
|
||||
<Version>1.3.0</Version>
|
||||
<Version>1.5.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MonkeyCache.FileStore">
|
||||
<Version>1.3.0</Version>
|
||||
<Version>1.5.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="PCLCrypto" Version="2.0.147" />
|
||||
<PackageReference Include="PCLStorage" Version="1.0.2" />
|
||||
<PackageReference Include="Plugin.BluetoothLE">
|
|
@ -17,6 +17,10 @@ using System.Threading;
|
|||
using TINK.Model.Settings;
|
||||
using Plugin.Permissions;
|
||||
using TINK.Services.BluetoothLock.Crypto;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Services;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Essentials;
|
||||
#if ARENDI
|
||||
using Arendi.BleLibrary.Local;
|
||||
#endif
|
||||
|
@ -45,38 +49,100 @@ namespace TINK
|
|||
// Root model already exists, nothing to do.
|
||||
return m_oModelRoot;
|
||||
}
|
||||
|
||||
|
||||
// Get folder where to read settings from
|
||||
var specialFolders = DependencyService.Get<ISpecialFolder>();
|
||||
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
|
||||
|
||||
// Delete attachtment from previous session.
|
||||
DeleteAttachment(internalPersonalDir);
|
||||
|
||||
// Setup logger using default settings.
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.ControlledBy(new LoggingLevelSwitch { MinimumLevel = Model.Settings.Settings.DEFAULTLOGGINLEVEL })
|
||||
.WriteTo.Debug()
|
||||
.WriteTo.File(internalPersonalDir, Model.Logging.RollingInterval.Session)
|
||||
.CreateLogger();
|
||||
|
||||
// Subscribe to any unhandled/ unobserved exceptions.
|
||||
AppDomain.CurrentDomain.UnhandledException += (sender, unobservedTaskExceptionEventArgs) => { Log.Fatal("Unobserved task exception: {Exception}", unobservedTaskExceptionEventArgs.ExceptionObject); };
|
||||
TaskScheduler.UnobservedTaskException += (sender, unhandledExceptionEventArgs) => { Log.Fatal("Unhandled exception: {Exception}", unhandledExceptionEventArgs.Exception); };
|
||||
|
||||
// Restore last model state from json- file.
|
||||
Dictionary<string, string> settingsJSON = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
settingsJSON = JsonSettingsDictionary.Deserialize(specialFolders.GetInternalPersonalDir());
|
||||
settingsJSON = JsonSettingsDictionary.Deserialize(internalPersonalDir);
|
||||
}
|
||||
catch (Exception l_oException)
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("Reading application settings from file failed.", l_oException);
|
||||
Log.Error("Reading application settings from file failed.", exception);
|
||||
}
|
||||
|
||||
var settings = new Model.Settings.Settings(
|
||||
JsonSettingsDictionary.GetGroupFilterMapPage(settingsJSON),
|
||||
JsonSettingsDictionary.GetGoupFilterSettings(settingsJSON),
|
||||
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
|
||||
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
|
||||
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
|
||||
JsonSettingsDictionary.GetExpiresAfter(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveLockService(settingsJSON),
|
||||
JsonSettingsDictionary.GetConnectTimeout(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveGeolocationService(settingsJSON),
|
||||
JsonSettingsDictionary.GetCenterMapToCurrentLocation(settingsJSON),
|
||||
JsonSettingsDictionary.GetLogToExternalFolder(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsSiteCachingOn(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveTheme(settingsJSON));
|
||||
Model.Settings.Settings settings;
|
||||
try
|
||||
{
|
||||
settings = new Model.Settings.Settings(
|
||||
JsonSettingsDictionary.GetGroupFilterMapPage(settingsJSON),
|
||||
JsonSettingsDictionary.GetGoupFilterSettings(settingsJSON),
|
||||
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
|
||||
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
|
||||
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsReportLevelVerbose(settingsJSON),
|
||||
JsonSettingsDictionary.GetExpiresAfter(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveLockService(settingsJSON),
|
||||
JsonSettingsDictionary.GetConnectTimeout(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveGeolocationService(settingsJSON),
|
||||
JsonSettingsDictionary.GetCenterMapToCurrentLocation(settingsJSON),
|
||||
JsonSettingsDictionary.GetLogToExternalFolder(settingsJSON),
|
||||
JsonSettingsDictionary.GetIsSiteCachingOn(settingsJSON),
|
||||
JsonSettingsDictionary.GetActiveTheme(settingsJSON));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("Deserializing application settings from dictionary failed.", exception);
|
||||
settings = new Model.Settings.Settings();
|
||||
}
|
||||
|
||||
var store = new Store(settings.ActiveUri.GetHashCode().ToString());
|
||||
var l_oAccount = new Account(store.Load());
|
||||
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|
||||
|| settings.LogToExternalFolder)
|
||||
{
|
||||
// Eigher
|
||||
// - logging is not set to default value or
|
||||
// - logging is performed to external folder.
|
||||
// Need to reconfigure.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.ControlledBy(new LoggingLevelSwitch(settings.MinimumLogEventLevel))
|
||||
.WriteTo.Debug()
|
||||
.WriteTo.File(!settings.LogToExternalFolder ? internalPersonalDir : specialFolders.GetExternalFilesDir(), Model.Logging.RollingInterval.Session)
|
||||
.CreateLogger();
|
||||
}
|
||||
|
||||
// Get auth cookie
|
||||
Log.Debug("Get auth cookie.");
|
||||
IStore store = null;
|
||||
|
||||
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
|
||||
if (lastVersion > new Version(3, 0, 173))
|
||||
GeolocationServicesContainer.SetActive(settings.ActiveGeolocationService);
|
||||
|
||||
if (new Version(0, 0, 0) < lastVersion
|
||||
&& lastVersion <= new Version(3, 0, 234))
|
||||
{
|
||||
// Version 3.0.245 and older used Xamarin.Auth.AccountStore to securely store data.
|
||||
// Later version s use Xamarin.Essentials Secure Storage.
|
||||
store = new StoreLegacy(settings.ActiveUri.GetHashCode().ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Either
|
||||
// - frist install or
|
||||
// - version whitch uses secure storage
|
||||
// detected.
|
||||
store = new Store();
|
||||
}
|
||||
|
||||
Barrel.ApplicationId = "TINKApp";
|
||||
|
||||
|
@ -85,17 +151,17 @@ namespace TINK
|
|||
var appInfoService = DependencyService.Get<IAppInfo>();
|
||||
|
||||
// Create new app instnace.
|
||||
Log.Debug("Constructing main model...");
|
||||
m_oModelRoot = new TinkApp(
|
||||
settings,
|
||||
store, // Manages user account
|
||||
(isConnected, activeUri, sessionCookie, mail, expiresAfter) => ConnectorFactory.Create(isConnected, activeUri, $"TINKApp/{appInfoService.Version}", sessionCookie, mail, expiresAfter),
|
||||
null, /* geolocationService */
|
||||
DependencyService.Get<IGeolodationDependent>(),
|
||||
(isConnected, activeUri, sessionCookie, mail, expiresAfter) => ConnectorFactory.Create(isConnected, activeUri, $"sharee.bike/{appInfoService.Version}", sessionCookie, mail, expiresAfter),
|
||||
GeolocationServicesContainer,
|
||||
null, /* locksService */
|
||||
DependencyService.Get<IDevice>(),
|
||||
DependencyService.Get<ISmartDevice>(),
|
||||
specialFolders,
|
||||
new Cipher(),
|
||||
CrossPermissions.Current,
|
||||
null, // Permissions, no more used.
|
||||
#if ARENDI
|
||||
DependencyService.Get<ICentral>(),
|
||||
#else
|
||||
|
@ -107,6 +173,7 @@ namespace TINK
|
|||
lastVersion: JsonSettingsDictionary.GetAppVersion(settingsJSON),
|
||||
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion());
|
||||
|
||||
Log.Debug("Main model successfully constructed.");
|
||||
return m_oModelRoot;
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +190,7 @@ namespace TINK
|
|||
MainPage = ModelRoot.WhatsNew.IsShowRequired
|
||||
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.MainPage()) // Show whats new info.
|
||||
: (Page) new View.MainPage(); // Just use TINKApp
|
||||
#elif USEFLYOU
|
||||
#elif USEFLYOUT
|
||||
// Use flyout page.
|
||||
MainPage = ModelRoot.WhatsNew.IsShowRequired
|
||||
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.Root.RootPage()) // Show whats new info.
|
||||
|
@ -138,12 +205,12 @@ namespace TINK
|
|||
}
|
||||
|
||||
/// <summary> Concatenates all log files to a single one. </summary>
|
||||
/// <returns>File name of attachment.</returns>
|
||||
/// <returns>Full file name of attachment.</returns>
|
||||
public static string CreateAttachment()
|
||||
{
|
||||
var l_oLogFiles = Log.Logger.GetLogFiles().ToArray();
|
||||
var sessionLogFiles = Log.Logger.GetLogFiles().ToArray();
|
||||
|
||||
if (l_oLogFiles.Length < 1)
|
||||
if (sessionLogFiles.Length < 1)
|
||||
{
|
||||
// Either
|
||||
// - there is no logging file
|
||||
|
@ -151,14 +218,14 @@ namespace TINK
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
var l_oLogPath = System.IO.Path.Combine(ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
var fullLogFileName = System.IO.Path.Combine(ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
|
||||
// Stop logging to avoid file access exception.
|
||||
Log.CloseAndFlush();
|
||||
|
||||
System.IO.File.WriteAllLines(
|
||||
l_oLogPath,
|
||||
l_oLogFiles.SelectMany(name =>
|
||||
fullLogFileName,
|
||||
sessionLogFiles.SelectMany(name =>
|
||||
(new List<string> { $"{{\"SessionFileName\":\"{name}\"}}" })
|
||||
.Concat(System.IO.File.ReadLines(name).ToArray())));
|
||||
|
||||
|
@ -169,33 +236,21 @@ namespace TINK
|
|||
.WriteTo.File(ModelRoot.LogFileParentFolder, Model.Logging.RollingInterval.Session)
|
||||
.CreateLogger();
|
||||
|
||||
return l_oLogPath;
|
||||
return fullLogFileName;
|
||||
}
|
||||
|
||||
/// <summary>Deletes an attachment if there is one.</summary>
|
||||
private static void DeleteAttachment()
|
||||
/// <param name="folder">Folder to delete, is null folder is queried from model.</param>
|
||||
private static void DeleteAttachment(string folder = null)
|
||||
{
|
||||
var l_oAttachment = System.IO.Path.Combine(ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
if (!System.IO.File.Exists(l_oAttachment))
|
||||
var attachment = System.IO.Path.Combine(folder ?? ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
|
||||
if (!System.IO.File.Exists(attachment))
|
||||
{
|
||||
// No attachment found.
|
||||
return;
|
||||
}
|
||||
|
||||
System.IO.File.Delete(l_oAttachment);
|
||||
}
|
||||
|
||||
|
||||
/// <summary> TINK app starts up.</summary>
|
||||
protected override void OnStart()
|
||||
{
|
||||
DeleteAttachment();
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.ControlledBy(new LoggingLevelSwitch { MinimumLevel = ModelRoot.Level.MinimumLevel })
|
||||
.WriteTo.Debug()
|
||||
.WriteTo.File(ModelRoot.LogFileParentFolder, Model.Logging.RollingInterval.Session)
|
||||
.CreateLogger();
|
||||
System.IO.File.Delete(attachment);
|
||||
}
|
||||
|
||||
protected override void OnSleep()
|
||||
|
@ -227,5 +282,26 @@ namespace TINK
|
|||
|
||||
return LogEventLevel.Error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service to manage permissions (location) of the app.
|
||||
/// </summary>
|
||||
public static Plugin.Permissions.Abstractions.IPermissions PermissionsService => CrossPermissions.Current;
|
||||
|
||||
/// <summary>
|
||||
/// Service to manage bluetooth stack.
|
||||
/// </summary>
|
||||
public static Plugin.BLE.Abstractions.Contracts.IBluetoothLE BluetoothService => Plugin.BLE.CrossBluetoothLE.Current;
|
||||
|
||||
/// <summary>
|
||||
/// Service container to manage geolocation services.
|
||||
/// </summary>
|
||||
public static IServicesContainer<IGeolocation> GeolocationServicesContainer { get; }
|
||||
= new Services.ServicesContainerMutable<Model.Services.Geolocation.IGeolocation>(
|
||||
new HashSet<Model.Services.Geolocation.IGeolocation> {
|
||||
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
|
||||
new GeolocationService(DependencyService.Get<IGeolodationDependent>()) },
|
||||
typeof(LastKnownGeolocationService).FullName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,19 +7,19 @@ namespace TINK
|
|||
{
|
||||
public static class BackdoorMethodHelpers
|
||||
{
|
||||
public static void DoTapPage(string stationIndex )
|
||||
public static void DoTapPage(string stationId )
|
||||
{
|
||||
Serilog.Log.Information($"Request via backdoor to tap station {stationIndex}.");
|
||||
Serilog.Log.Information($"Request via backdoor to tap station {stationId}.");
|
||||
var currentPage = GetCurrentPage();
|
||||
var mapPageViewModel = (currentPage as MapPage)?.BindingContext as MapPageViewModel;
|
||||
if (mapPageViewModel == null)
|
||||
{
|
||||
Serilog.Log.Error($"Request via backdoor to tap station {stationIndex} aborted because current page is not of expected type {typeof(MapPage).Name}. Type detected is {currentPage.GetType().Name}.");
|
||||
Serilog.Log.Error($"Request via backdoor to tap station {stationId} aborted because current page is not of expected type {typeof(MapPage).Name}. Type detected is {currentPage.GetType().Name}.");
|
||||
return;
|
||||
}
|
||||
|
||||
Serilog.Log.Information($"Invoking member to tap.");
|
||||
mapPageViewModel?.OnStationClicked(int.Parse(stationIndex));
|
||||
mapPageViewModel?.OnStationClicked(stationId);
|
||||
}
|
||||
|
||||
/// <summary> Gets the current page assumed that app is master detail page.</summary>
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
|
||||
namespace TINK.Model.User.Account
|
||||
{
|
||||
public class Store : IStore
|
||||
public class StoreLegacy : IStore
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the name of the application.
|
||||
|
@ -21,12 +23,9 @@ namespace TINK.Model.User.Account
|
|||
/// <summary> Holds the id of the session. </summary>
|
||||
private const string KEY_DEBUGLEVEL = "DebugLevel";
|
||||
|
||||
private Store()
|
||||
{ }
|
||||
|
||||
public Store(string p_strCopriHostHash)
|
||||
public StoreLegacy(string copriHostHash)
|
||||
{
|
||||
m_strCopriHostHash = p_strCopriHostHash
|
||||
m_strCopriHostHash = copriHostHash
|
||||
?? throw new ArgumentException("Can not construct account object. Copri hash must not be null.");
|
||||
}
|
||||
|
||||
|
@ -36,26 +35,26 @@ namespace TINK.Model.User.Account
|
|||
/// Reads mail address and password from account store.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IAccount Load()
|
||||
public async Task<IAccount> Load()
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
#if !__IOS__
|
||||
var account = Xamarin.Auth.AccountStore.Create("System.Char[]").FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
var xamAccountStore = Xamarin.Auth.AccountStore.Create("System.Char[]").FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
#else
|
||||
var account = Xamarin.Auth.AccountStore.Create().FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
var xamAccountStore = Xamarin.Auth.AccountStore.Create().FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
#endif
|
||||
if (account == null)
|
||||
if (xamAccountStore == null)
|
||||
{
|
||||
// Nothing t do if account cannot be accessed.
|
||||
return new EmptyAccount();
|
||||
}
|
||||
|
||||
return new Account(
|
||||
account.Username,
|
||||
xamAccountStore.Username,
|
||||
string.Empty,
|
||||
account.Properties.ContainsKey(KEY_SESSIONID) ? account.Properties[KEY_SESSIONID] : null,
|
||||
account.Properties.ContainsKey(KEY_GROUP) ? TextToTypeHelper.GetGroup(account.Properties[KEY_GROUP]) : new List<string>(),
|
||||
account.Properties.ContainsKey(KEY_DEBUGLEVEL) && !string.IsNullOrEmpty(account.Properties[KEY_DEBUGLEVEL]) ? Permissions.Parse<Permissions>(account.Properties[KEY_DEBUGLEVEL]) : Permissions.None);
|
||||
xamAccountStore.Properties.ContainsKey(KEY_SESSIONID) ? xamAccountStore.Properties[KEY_SESSIONID] : null,
|
||||
xamAccountStore.Properties.ContainsKey(KEY_GROUP) && !string.IsNullOrEmpty(xamAccountStore.Properties[KEY_GROUP]) ? JsonConvert.DeserializeObject<IEnumerable<string>>(xamAccountStore.Properties[KEY_GROUP]) : new string[0],
|
||||
xamAccountStore.Properties.ContainsKey(KEY_DEBUGLEVEL) && !string.IsNullOrEmpty(xamAccountStore.Properties[KEY_DEBUGLEVEL]) ? Permissions.Parse<Permissions>(xamAccountStore.Properties[KEY_DEBUGLEVEL]) : Permissions.None);
|
||||
#else
|
||||
return new Account(
|
||||
string.Empty,
|
||||
|
@ -70,22 +69,22 @@ namespace TINK.Model.User.Account
|
|||
/// <summary>
|
||||
/// Writes mail address and password to account store.
|
||||
/// </summary>
|
||||
/// <param name="p_oAccount"></param>
|
||||
public void Save(IAccount p_oAccount)
|
||||
/// <param name="account"></param>
|
||||
public async Task Save(IAccount account)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
Xamarin.Auth.Account account = new Xamarin.Auth.Account
|
||||
Xamarin.Auth.Account xamAccount = new Xamarin.Auth.Account
|
||||
{
|
||||
Username = p_oAccount.Mail
|
||||
Username = account.Mail
|
||||
};
|
||||
|
||||
account.Properties.Add(KEY_SESSIONID, p_oAccount?.SessionCookie);
|
||||
account.Properties.Add(KEY_GROUP, p_oAccount?.Group?.GetGroup());
|
||||
account.Properties.Add(KEY_DEBUGLEVEL, p_oAccount.DebugLevel.ToString());
|
||||
xamAccount.Properties.Add(KEY_SESSIONID, account?.SessionCookie);
|
||||
xamAccount.Properties.Add(KEY_GROUP, JsonConvert.SerializeObject(account?.Group ?? new string[0]));
|
||||
xamAccount.Properties.Add(KEY_DEBUGLEVEL, account.DebugLevel.ToString());
|
||||
#if !__IOS__
|
||||
Xamarin.Auth.AccountStore.Create("System.Char[]").Save(account, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
Xamarin.Auth.AccountStore.Create("System.Char[]").Save(xamAccount, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
#else
|
||||
Xamarin.Auth.AccountStore.Create().Save(account, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
Xamarin.Auth.AccountStore.Create().Save(xamAccount, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -93,26 +92,25 @@ namespace TINK.Model.User.Account
|
|||
/// <summary>
|
||||
/// Deletes mail address and password from account store.
|
||||
/// </summary>
|
||||
public IAccount Delete(IAccount p_oAccount)
|
||||
public IAccount Delete(IAccount account)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
#if !__IOS__
|
||||
var account = Xamarin.Auth.AccountStore.Create("System.Char[]").FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
var xamAccountStore = Xamarin.Auth.AccountStore.Create("System.Char[]").FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
#else
|
||||
var account = Xamarin.Auth.AccountStore.Create().FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
var xamAccountStore = Xamarin.Auth.AccountStore.Create().FindAccountsForService($"{M_STR_APPNAME}_{m_strCopriHostHash}").FirstOrDefault();
|
||||
#endif
|
||||
if (account == null)
|
||||
if (xamAccountStore == null)
|
||||
{
|
||||
return new EmptyAccount();
|
||||
}
|
||||
#if !__IOS__
|
||||
Xamarin.Auth.AccountStore.Create("System.Char[]").Delete(account, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
Xamarin.Auth.AccountStore.Create("System.Char[]").Delete(xamAccountStore, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
#else
|
||||
Xamarin.Auth.AccountStore.Create().Delete(account, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
Xamarin.Auth.AccountStore.Create().Delete(xamAccountStore, $"{M_STR_APPNAME}_{m_strCopriHostHash}");
|
||||
#endif
|
||||
#endif
|
||||
return new EmptyAccount();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)BackdoorMethodHelpers.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Services\BluetoothLock\Arendi\Central.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\FeesAndBikes\HelpContactViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootShell\AppShellViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootFlyout\RootPageViewModel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)View\Account\AccountPage.xaml.cs">
|
||||
|
@ -76,6 +75,7 @@
|
|||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)View\WhatsNew\WhatsNewPage.xaml.cs">
|
||||
<DependentUpon>WhatsNewPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Model\User\Account\Store.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\ViewModelResourceHelper.cs" />
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using System.Threading.Tasks;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using System;
|
||||
using TINK.Model.Device;
|
||||
using TINK.ViewModel.Account;
|
||||
|
@ -10,7 +12,11 @@ using TINK.ViewModel.Account;
|
|||
namespace TINK.View.Account
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class AccountPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class AccountPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
AccountPageViewModel m_oViewModel = null;
|
||||
|
@ -31,18 +37,18 @@ namespace TINK.View.Account
|
|||
}
|
||||
|
||||
/// <summary> Displays altert message. </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
|
||||
/// <summary> Displays altert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
|
@ -50,32 +56,48 @@ namespace TINK.View.Account
|
|||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays an action sheet.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <param name="destruction"></param>
|
||||
/// <param name="p_oButtons">Buttons holding options to select.</param>
|
||||
/// <returns>Text selected</returns>
|
||||
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
|
||||
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
|
@ -86,6 +108,7 @@ namespace TINK.View.Account
|
|||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
|
||||
/// <summary>Delegate to perform navigation.</summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
@ -98,6 +121,7 @@ namespace TINK.View.Account
|
|||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
|
@ -122,7 +146,10 @@ namespace TINK.View.Account
|
|||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -15,7 +15,14 @@
|
|||
Padding="10">
|
||||
<Label
|
||||
FontAttributes="Bold"
|
||||
FontSize="Large"
|
||||
HorizontalTextAlignment="Center"
|
||||
Text="{Binding Name}"/>
|
||||
<Label
|
||||
FontAttributes="Bold"
|
||||
HorizontalTextAlignment="Center"
|
||||
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
|
||||
Text="{Binding DisplayId}"/>
|
||||
<Label
|
||||
Text="{Binding StateText}"
|
||||
TextColor="{Binding StateColor}"/>
|
||||
|
|
|
@ -10,7 +10,9 @@ namespace TINK.View.BikesAtStation
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
using TINK.View.MasterDetail;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using TINK.Model;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
|
@ -23,7 +25,11 @@ namespace TINK.View.BikesAtStation
|
|||
using Xamarin.CommunityToolkit.Extensions;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class BikesAtStationPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
|
||||
private BikesAtStationPageViewModel m_oViewModel;
|
||||
|
@ -78,23 +84,27 @@ namespace TINK.View.BikesAtStation
|
|||
|
||||
m_oViewModel = new BikesAtStationPageViewModel(
|
||||
model.ActiveUser,
|
||||
model.Permissions,
|
||||
CrossBluetoothLE.Current,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
model.SelectedStation,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
model.Geolocation,
|
||||
App.GeolocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
this);
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<BikesAtStationPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
this.DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -130,12 +140,12 @@ namespace TINK.View.BikesAtStation
|
|||
}
|
||||
|
||||
/// <summary> Displays altert message.</summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strCancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAlert(string title, string message, string cancel)
|
||||
{
|
||||
await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
|
||||
await App.Current.MainPage.DisplayAlert(title, message, cancel);
|
||||
}
|
||||
|
||||
/// <summary> Displays altert message.</summary>
|
||||
|
@ -143,7 +153,7 @@ namespace TINK.View.BikesAtStation
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
|
@ -153,23 +163,37 @@ namespace TINK.View.BikesAtStation
|
|||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
/// <param name="p_strAccept">Text of accept button.</param>
|
||||
/// <param name="p_strCancel">Text of button.</param>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
|
||||
{
|
||||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary> Creates and a page an shows it.</summary>
|
||||
/// <remarks> When user is not logged in navigation to Login page is supported.</remarks>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
}
|
||||
public void ShowPage(ViewTypes p_oType, string title = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
|
@ -189,6 +213,7 @@ namespace TINK.View.BikesAtStation
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
|
@ -202,6 +227,12 @@ namespace TINK.View.BikesAtStation
|
|||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
}
|
||||
}
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -27,21 +27,31 @@ namespace TINK.View.Contact
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
|
@ -62,7 +72,10 @@ namespace TINK.View.Contact
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,15 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.CommunityToolkit.UI.Views;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class FeedbackPopup : Popup<FeedbackPopup.Result>
|
||||
{
|
||||
public FeedbackPopup ()
|
||||
|
@ -40,7 +35,11 @@ namespace TINK.View
|
|||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
#if USCSHARP9
|
||||
public class Result : IViewService.IUserFeedback
|
||||
#else
|
||||
public class Result : IUserFeedback
|
||||
#endif
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
|
@ -54,7 +53,6 @@ namespace TINK.View
|
|||
/// or both.
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using TINK.ViewModel.Contact;
|
||||
using TINK.Model;
|
||||
|
||||
namespace TINK.View.Contact
|
||||
{
|
||||
|
@ -16,8 +15,10 @@ namespace TINK.View.Contact
|
|||
InitializeComponent();
|
||||
|
||||
ViewModel = new HelpContactViewModel(
|
||||
TINK.App.ModelRoot.NextActiveUri.Host,
|
||||
TINK.App.ModelRoot.IsSiteCachingOn);
|
||||
App.ModelRoot.NextActiveUri.Host,
|
||||
App.ModelRoot.IsSiteCachingOn,
|
||||
resourceName => ViewModelResourceHelper.GetSource(resourceName));
|
||||
|
||||
BindingContext = ViewModel;
|
||||
|
||||
/// Info about renting.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Info.BikeInfo;
|
||||
using Xamarin.Forms;
|
||||
|
@ -9,9 +11,13 @@ using Xamarin.Forms.Xaml;
|
|||
namespace TINK.View.Info.BikeInfo
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService, IDetailPage
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class BikeInfoCarouselPage : CarouselPage, IViewService
|
||||
#endif
|
||||
{
|
||||
public BikeInfoCarouselPage ()
|
||||
public BikeInfoCarouselPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
|
@ -36,13 +42,23 @@ namespace TINK.View.Info.BikeInfo
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
|
@ -56,14 +72,19 @@ namespace TINK.View.Info.BikeInfo
|
|||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
}
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
|
@ -85,6 +106,7 @@ namespace TINK.View.Info.BikeInfo
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
|
@ -98,6 +120,11 @@ namespace TINK.View.Info.BikeInfo
|
|||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Device;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
@ -9,9 +11,13 @@ using Xamarin.Forms.Xaml;
|
|||
namespace TINK.View.Login
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class LoginPage : ContentPage, IViewService, IDetailPage
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class LoginPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class LoginPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
public LoginPage ()
|
||||
public LoginPage ()
|
||||
{
|
||||
InitializeComponent ();
|
||||
|
||||
|
@ -44,25 +50,40 @@ namespace TINK.View.Login
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
}
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
@ -80,6 +101,7 @@ namespace TINK.View.Login
|
|||
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Delegate to perform navigation.
|
||||
/// </summary>
|
||||
|
@ -93,6 +115,11 @@ namespace TINK.View.Login
|
|||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,21 +1,26 @@
|
|||
using Plugin.Connectivity;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace TINK.View.Map
|
||||
{
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using Serilog;
|
||||
using TINK.ViewModel.Map;
|
||||
using Xamarin.Forms.GoogleMaps;
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class MapPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class MapPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> View model to notify about whether page appears or hides. </summary>
|
||||
private MapPageViewModel m_oMapPageViewModel;
|
||||
private MapPageViewModel MapPageViewModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs map page instance.
|
||||
|
@ -41,13 +46,23 @@ namespace TINK.View.Map
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
|
@ -61,14 +76,18 @@ namespace TINK.View.Map
|
|||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
m_oNavigationMasterDetail.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
}
|
||||
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to display.</param>
|
||||
|
@ -87,31 +106,34 @@ namespace TINK.View.Map
|
|||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
{
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
var page = Activator.CreateInstance(p_oTypeOfPage.GetViewType()) as IDetailPage;
|
||||
#else
|
||||
var page = Activator.CreateInstance(p_oTypeOfPage.GetViewType());
|
||||
#endif
|
||||
if (page == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
page.NavigationMasterDetail = m_oNavigationMasterDetail;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
page.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
|
||||
await Navigation.PushAsync((Page)page);
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
/// <summary> Delegate to perform navigation. </summary>
|
||||
private INavigationMasterDetail m_oNavigationMasterDetail;
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary> Delegate to perform navigation.</summary>
|
||||
public INavigationMasterDetail NavigationMasterDetail
|
||||
{
|
||||
set
|
||||
{
|
||||
m_oNavigationMasterDetail = value;
|
||||
}
|
||||
}
|
||||
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
|
@ -119,39 +141,99 @@ namespace TINK.View.Map
|
|||
protected async override void OnAppearing()
|
||||
{
|
||||
// Pass reference to member Navigation to show bikes at station x dialog.
|
||||
#if TRYNOTBACKSTYLE
|
||||
m_oMapPageViewModel = new MapPageViewModel();
|
||||
#else
|
||||
m_oMapPageViewModel = new MapPageViewModel(
|
||||
App.ModelRoot,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
#endif
|
||||
|
||||
BindingContext = m_oMapPageViewModel;
|
||||
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
try
|
||||
{
|
||||
TINKButton.BackgroundColor = Color.LightGray;
|
||||
TINKButton.BorderColor = Color.Black;
|
||||
TINKButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
KonradButton.BackgroundColor = Color.LightGray;
|
||||
KonradButton.BorderColor = Color.Black;
|
||||
KonradButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
Log.ForContext<MainPage>().Verbose("Constructing map page view model.");
|
||||
|
||||
#if TRYNOTBACKSTYLE
|
||||
m_oMapPageViewModel = new MapPageViewModel();
|
||||
#else
|
||||
MapPageViewModel = new MapPageViewModel(
|
||||
App.ModelRoot,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
App.GeolocationServicesContainer.Active,
|
||||
(mapspan) => MyMap.MoveToRegion(mapspan),
|
||||
this,
|
||||
Navigation);
|
||||
#endif
|
||||
} catch (Exception exception)
|
||||
{
|
||||
|
||||
Log.ForContext<MainPage>().Error("Constructing map page view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
m_oMapPageViewModel.NavigationMasterDetail = m_oNavigationMasterDetail;
|
||||
try
|
||||
{
|
||||
BindingContext = MapPageViewModel;
|
||||
|
||||
base.OnAppearing();
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MainPage>().Error("Setting binding/ navigaton on map page failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
MapPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.Uris.ActiveUri,
|
||||
App.ModelRoot.GroupFilterMapPage);
|
||||
|
||||
await m_oMapPageViewModel.OnAppearing();
|
||||
try
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
TINKButton.BackgroundColor = Color.LightGray;
|
||||
TINKButton.BorderColor = Color.Black;
|
||||
TINKButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
KonradButton.BackgroundColor = Color.LightGray;
|
||||
KonradButton.BorderColor = Color.Black;
|
||||
KonradButton.Margin = new Thickness(10, 10, 10, 10);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MainPage>().Error("IOS specific styling of map page failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
base.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Continue because styling is not essential.
|
||||
Log.ForContext<MainPage>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Pre move and scanle maps to avoid initial display of map in Rome.
|
||||
Log.ForContext<MainPage>().Verbose("Moving and scaling map.");
|
||||
MapPageViewModel.MoveAndScale(
|
||||
(mapSpan) => MyMap.MoveToRegion(mapSpan),
|
||||
App.ModelRoot.Uris.ActiveUri,
|
||||
App.ModelRoot.GroupFilterMapPage);
|
||||
|
||||
}
|
||||
catch(Exception exception)
|
||||
{
|
||||
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
|
||||
Log.ForContext<MainPage>().Error("Moving and scaling map failed. {Exception}", exception);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<MainPage>().Verbose("Invoking OnAppearing on map page view model.");
|
||||
await MapPageViewModel.OnAppearing();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MainPage>().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -160,10 +242,10 @@ namespace TINK.View.Map
|
|||
/// </summary>
|
||||
protected override async void OnDisappearing()
|
||||
{
|
||||
if (m_oMapPageViewModel != null)
|
||||
if (MapPageViewModel != null)
|
||||
{
|
||||
// View model might be null.
|
||||
await m_oMapPageViewModel?.OnDisappearing();
|
||||
await MapPageViewModel?.OnDisappearing();
|
||||
}
|
||||
|
||||
base.OnDisappearing();
|
||||
|
|
|
@ -4,7 +4,9 @@ using System.Linq;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
@ -58,21 +60,25 @@ namespace TINK.View.MyBikes
|
|||
|
||||
m_oViewModel = new MyBikesPageViewModel(
|
||||
model.ActiveUser,
|
||||
model.Permissions,
|
||||
CrossBluetoothLE.Current,
|
||||
App.PermissionsService,
|
||||
App.BluetoothService,
|
||||
Device.RuntimePlatform,
|
||||
() => model.GetIsConnected(),
|
||||
(isConnected) => model.GetConnector(isConnected),
|
||||
model.Geolocation,
|
||||
App.GeolocationServicesContainer.Active,
|
||||
model.LocksServices.Active,
|
||||
model.Polling,
|
||||
(d, obj) => synchronizationContext.Post(d, obj),
|
||||
this);
|
||||
model.SmartDevice,
|
||||
this)
|
||||
{
|
||||
IsReportLevelVerbose = model.IsReportLevelVerbose
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<MyBikesPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
|
||||
this.DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
|
||||
return;
|
||||
|
||||
}
|
||||
|
@ -123,6 +129,16 @@ namespace TINK.View.MyBikes
|
|||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary>
|
||||
/// Displays alert message.
|
||||
/// </summary>
|
||||
|
@ -136,14 +152,14 @@ namespace TINK.View.MyBikes
|
|||
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
|
@ -165,6 +181,10 @@ namespace TINK.View.MyBikes
|
|||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -3,7 +3,9 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
|
@ -19,7 +21,11 @@ namespace TINK.View.Root
|
|||
// - switch to login page form bikes at station page if not yet logged in
|
||||
/// </remarks>
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class RootPage : FlyoutPage, INavigationMasterDetail
|
||||
#else
|
||||
public partial class RootPage : FlyoutPage
|
||||
#endif
|
||||
{
|
||||
public RootPage()
|
||||
{
|
||||
|
@ -35,6 +41,7 @@ namespace TINK.View.Root
|
|||
return;
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
var detailPage = navigationPage.RootPage as IDetailPage;
|
||||
if (detailPage == null)
|
||||
{
|
||||
|
@ -42,6 +49,7 @@ namespace TINK.View.Root
|
|||
}
|
||||
|
||||
detailPage.NavigationMasterDetail = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,12 +78,14 @@ namespace TINK.View.Root
|
|||
var page = (Page)Activator.CreateInstance(typeOfPage);
|
||||
page.Title = title;
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
if (page is IDetailPage detailPage)
|
||||
{
|
||||
// Detail page needs reference to perform navigation.
|
||||
// Examples see above in xdoc of class.
|
||||
detailPage.NavigationMasterDetail = this;
|
||||
}
|
||||
#endif
|
||||
|
||||
Detail = new NavigationPage(page);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using TINK.Model;
|
||||
using TINK.Services;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.View.Themes;
|
||||
using TINK.ViewModel.Root;
|
||||
using Xamarin.Forms;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using TINK.View.Info.BikeInfo;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.ViewModel.MasterDetail;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
@ -13,8 +15,12 @@ namespace TINK.View
|
|||
public delegate void ShowPageDelegate(Type p_oType, string p_strTitle = null);
|
||||
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class MainPage : MasterDetailPage, INavigationMasterDetail
|
||||
{
|
||||
#else
|
||||
public partial class MainPage : MasterDetailPage
|
||||
#endif
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -29,6 +35,7 @@ namespace TINK.View
|
|||
return;
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
var detailPage = navigationPage.RootPage as IDetailPage;
|
||||
if (detailPage == null)
|
||||
{
|
||||
|
@ -36,6 +43,7 @@ namespace TINK.View
|
|||
}
|
||||
|
||||
detailPage.NavigationMasterDetail = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary> Creates and a page an shows it.</summary>
|
||||
|
@ -50,11 +58,13 @@ namespace TINK.View
|
|||
var page = (Page)Activator.CreateInstance(p_oTypeOfPage);
|
||||
page.Title = p_strTitle ?? Helper.GetCaption(p_oTypeOfPage);
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
var l_oPage = page as IDetailPage;
|
||||
if (l_oPage != null)
|
||||
{
|
||||
l_oPage.NavigationMasterDetail = this;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !BACKSTYLE
|
||||
// When bike info page is shown do not allow to close this carousel before all pages were displayed.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingMapPage}"
|
||||
Route="MapPage"
|
||||
ContentTemplate="{DataTemplate mappage:MapPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
<FontImageSource Glyph="{StaticResource IconMap}" Color="Black" FontFamily="FA-S" />
|
||||
|
@ -49,6 +50,7 @@
|
|||
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
|
||||
<ShellContent
|
||||
Title="{x:Static resources:AppResources.MarkingLogin}"
|
||||
Route="LoginPage"
|
||||
IsVisible="{Binding IsLoginPageVisible}"
|
||||
ContentTemplate="{DataTemplate login:LoginPage}">
|
||||
<ShellContent.FlyoutIcon>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<conv:PermissionToVisibleConverter x:Key="PickLockServiceImplementation_Converter" VisibleFlag="PickLockServiceImplementation"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="PickLocationServiceImplementation_Converter" VisibleFlag="PickLocationServiceImplementation"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="PickLoggingLevel_Converter" VisibleFlag="PickLoggingLevel"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="ReportLevel_Converter" VisibleFlag="ReportLevel"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="ShowDiagnostics_Converter" VisibleFlag="ShowDiagnostics"/>
|
||||
<conv:PermissionToVisibleConverter x:Key="SwitchSiteCaching_Converter" VisibleFlag="SwitchNoSiteCaching"/>
|
||||
</ContentPage.Resources>
|
||||
|
@ -176,6 +177,18 @@
|
|||
IsEnabled="{Binding IsLogToExternalFolderVisible}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Logging -->
|
||||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ReportLevel_Converter}}"
|
||||
Text="Verbose error messages" />
|
||||
<Switch
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource ReportLevel_Converter}}"
|
||||
IsToggled="{Binding IsReportLevelVerbose}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
<Frame
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource Frame_Converter}}">
|
||||
<!-- Display of parameters -->
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using System.Threading.Tasks;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using System;
|
||||
using TINK.Model.Device;
|
||||
using Xamarin.CommunityToolkit.Extensions;
|
||||
|
@ -10,7 +12,11 @@ using Xamarin.CommunityToolkit.Extensions;
|
|||
namespace TINK.View.Settings
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
|
||||
#else
|
||||
public partial class SettingsPage : ContentPage, IViewService
|
||||
#endif
|
||||
{
|
||||
/// <summary> Refernce to view model. </summary>
|
||||
SettingsPageViewModel m_oViewModel = null;
|
||||
|
@ -24,6 +30,7 @@ namespace TINK.View.Settings
|
|||
|
||||
m_oViewModel = new SettingsPageViewModel(
|
||||
l_oModel,
|
||||
App.GeolocationServicesContainer,
|
||||
this);
|
||||
|
||||
BindingContext = m_oViewModel;
|
||||
|
@ -43,13 +50,23 @@ namespace TINK.View.Settings
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary> Displays alert message.</summary>
|
||||
/// <param name="p_strTitle">Title of message.</param>
|
||||
/// <param name="p_strMessage">Message to display.</param>
|
||||
|
@ -71,12 +88,18 @@ namespace TINK.View.Settings
|
|||
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
|
||||
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>
|
||||
/// Creates and a page an shows it.
|
||||
/// </summary>
|
||||
/// <param name="p_oTypeOfPage">Type of page to show.</param>
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
/// <summary> Pushes a page onto the modal stack. </summary>
|
||||
/// <param name="p_oTypeOfPage">Page to display.</param>
|
||||
|
@ -87,6 +110,7 @@ namespace TINK.View.Settings
|
|||
public Task PopModalAsync()
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
/// <summary>Delegate to perform navigation.</summary>
|
||||
private INavigationMasterDetail m_oNavigation;
|
||||
|
||||
|
@ -98,6 +122,7 @@ namespace TINK.View.Settings
|
|||
set { m_oNavigation = value; }
|
||||
}
|
||||
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
|
@ -118,7 +143,11 @@ namespace TINK.View.Settings
|
|||
public async Task PushAsync(ViewTypes p_oTypeOfPage)
|
||||
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
|
||||
#if USCSHARP9
|
||||
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#else
|
||||
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
|
||||
#endif
|
||||
|
||||
#if USERFEEDBACKDLG_TRYOUT
|
||||
public async void OnFeedbackClickedAsync(object sender, EventArgs ev)
|
||||
|
|
|
@ -28,13 +28,23 @@ namespace TINK.View.WhatsNew.Agb
|
|||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="cancel">Type of buttons.</param>
|
||||
public new async Task DisplayAdvancedAlert(
|
||||
public async Task DisplayAdvancedAlert(
|
||||
string title,
|
||||
string message,
|
||||
string details,
|
||||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
/// <summary> Invoked when page is shown. </summary>
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
|
@ -61,11 +71,19 @@ namespace TINK.View.WhatsNew.Agb
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -40,6 +40,16 @@ namespace TINK.View.WhatsNew
|
|||
string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
|
||||
|
||||
/// <summary> Displays detailed alert message.</summary>
|
||||
/// <param name="title">Title of message.</param>
|
||||
/// <param name="message">Message to display.</param>
|
||||
/// <param name="details">Detailed error description.</param>
|
||||
/// <param name="accept">Text of accept button.</param>
|
||||
/// <param name="cancel">Text of cancel button.</param>
|
||||
/// <returns>True if user pressed accept.</returns>
|
||||
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
|
||||
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
|
||||
|
||||
public Task PopModalAsync()
|
||||
{
|
||||
throw new NotImplementedException(); ;
|
||||
|
@ -57,12 +67,20 @@ namespace TINK.View.WhatsNew
|
|||
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
|
||||
}
|
||||
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
=> throw new NotImplementedException();
|
||||
#else
|
||||
/// <summary> Shows a page.</summary>
|
||||
/// <param name="route">Route of the page to show.</param>
|
||||
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
|
||||
#endif
|
||||
|
||||
#if USCSHARP9
|
||||
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#else
|
||||
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
|
|
|
@ -15,7 +15,9 @@ using TINK.View.Root;
|
|||
using TINK.View.Settings;
|
||||
using Xamarin.Forms;
|
||||
using TINK.ViewModel.MasterDetail;
|
||||
#if USEMASTERDETAIL || USEFLYOUT
|
||||
using TINK.View.MasterDetail;
|
||||
#endif
|
||||
using TINK.Services;
|
||||
using TINK.View.Themes;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace TINK.ViewModel.MasterDetail
|
|||
}
|
||||
else if (type == typeof(FeesAndBikesPage))
|
||||
{
|
||||
return "\uf153";
|
||||
return "\uf7d9";
|
||||
}
|
||||
else if (type == typeof(ContactPage))
|
||||
{
|
||||
|
|
|
@ -21,13 +21,13 @@ namespace TINK.Model.Bike.BC
|
|||
/// <summary> Constructs a bike object.</summary>
|
||||
protected BikeInfo(
|
||||
IStateInfo stateInfo,
|
||||
int id,
|
||||
string id,
|
||||
bool? isDemo = DEFAULTVALUEISDEMO,
|
||||
IEnumerable<string> group = null,
|
||||
WheelType? wheelType = null,
|
||||
TypeOfBike? typeOfBike = null,
|
||||
string description = null,
|
||||
int? currentStationId = null,
|
||||
string currentStationId = null,
|
||||
Uri operatorUri = null,
|
||||
TariffDescription tariffDescription = null)
|
||||
{
|
||||
|
@ -63,8 +63,8 @@ namespace TINK.Model.Bike.BC
|
|||
/// <param name="tariffDescription">Hold tariff description of bike.</param>
|
||||
/// <param name="wheelType"></param>
|
||||
public BikeInfo(
|
||||
int id,
|
||||
int? currentStationId,
|
||||
string id,
|
||||
string currentStationId,
|
||||
Uri operatorUri = null,
|
||||
TariffDescription tariffDescription = null,
|
||||
bool? isDemo = DEFAULTVALUEISDEMO,
|
||||
|
@ -99,13 +99,13 @@ namespace TINK.Model.Bike.BC
|
|||
/// <param name="code">Booking code.</param>
|
||||
/// <param name="p_oDateTimeNowProvider">Date time provider to calculate reaining time.</param>
|
||||
public BikeInfo(
|
||||
int id,
|
||||
string id,
|
||||
bool? isDemo,
|
||||
IEnumerable<string> group,
|
||||
WheelType? wheelType,
|
||||
TypeOfBike? typeOfBike,
|
||||
string description,
|
||||
int? stationId,
|
||||
string stationId,
|
||||
Uri operatorUri,
|
||||
TariffDescription tariffDescription,
|
||||
DateTime requestedAt,
|
||||
|
@ -142,13 +142,13 @@ namespace TINK.Model.Bike.BC
|
|||
/// <param name="mailAddress">Mail address of user which booked bike.</param>
|
||||
/// <param name="code">Booking code.</param>
|
||||
public BikeInfo(
|
||||
int id,
|
||||
string id,
|
||||
bool? isDemo,
|
||||
IEnumerable<string> group,
|
||||
WheelType? wheelType,
|
||||
TypeOfBike? typeOfBike,
|
||||
string description,
|
||||
int? currentStationId,
|
||||
string currentStationId,
|
||||
Uri operatorUri,
|
||||
TariffDescription tariffDescription,
|
||||
DateTime bookedAt,
|
||||
|
@ -179,7 +179,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// <summary>
|
||||
/// Station a which bike is located, null otherwise.
|
||||
/// </summary>
|
||||
public int? CurrentStation { get; }
|
||||
public string CurrentStation { get; }
|
||||
|
||||
/// <summary> Holds description about the tarif. </summary>
|
||||
public TariffDescription TariffDescription { get; }
|
||||
|
@ -192,7 +192,7 @@ namespace TINK.Model.Bike.BC
|
|||
get { return m_oStateInfo; }
|
||||
}
|
||||
|
||||
public int Id => Bike.Id;
|
||||
public string Id => Bike.Id;
|
||||
|
||||
public WheelType? WheelType => Bike.WheelType;
|
||||
|
||||
|
@ -210,7 +210,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// </summary>
|
||||
public new string ToString()
|
||||
{
|
||||
return $"Id={Bike.Id}{(Bike.WheelType != null ? $", wheel(s)={Bike.WheelType}" : string.Empty)}{(Bike.TypeOfBike != null ? $"type={Bike.TypeOfBike}" : "")}, state={State}, location={(CurrentStation.HasValue ? $"Station {CurrentStation}" : "On the road")}, is demo={IsDemo}.";
|
||||
return $"Id={Bike.Id}{(Bike.WheelType != null ? $", wheel(s)={Bike.WheelType}" : string.Empty)}{(Bike.TypeOfBike != null ? $"type={Bike.TypeOfBike}" : "")}, state={State}, location={(!string.IsNullOrEmpty(CurrentStation)? $"Station {CurrentStation}" : "On the road")}, is demo={IsDemo}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,13 @@ namespace TINK.Model.Bike.BC
|
|||
/// <param name="tariffDescription">Hold tariff description of bike.</param>
|
||||
/// <param name="stateInfo">Bike state info.</param>
|
||||
protected BikeInfoMutable(
|
||||
int id,
|
||||
string id,
|
||||
bool isDemo = BikeInfo.DEFAULTVALUEISDEMO,
|
||||
IEnumerable<string> group = null,
|
||||
WheelType? wheelType = null,
|
||||
TypeOfBike? typeOfBike = null,
|
||||
string description = null,
|
||||
int? currentStationId = null,
|
||||
string currentStationId = null,
|
||||
Uri operatorUri = null,
|
||||
TariffDescription tariffDescription = null,
|
||||
Func<DateTime> dateTimeProvider = null,
|
||||
|
@ -71,7 +71,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// Station a which bike is located, null otherwise.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int? CurrentStation { get; }
|
||||
public string CurrentStation { get; }
|
||||
|
||||
/// <summary> Holds description about the tarif. </summary>
|
||||
[DataMember]
|
||||
|
@ -94,7 +94,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// <summary> Unused member. </summary>
|
||||
IStateInfoMutable IBikeInfoMutable.State => m_oStateInfo;
|
||||
|
||||
public int Id => m_oBike.Id;
|
||||
public string Id => m_oBike.Id;
|
||||
|
||||
public bool IsDemo { get; }
|
||||
|
||||
|
@ -118,7 +118,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// <returns></returns>
|
||||
public new string ToString()
|
||||
{
|
||||
return $"Id={Id}{(WheelType != null ? $", wheel(s)={WheelType}" : string.Empty)}{(TypeOfBike != null ? $", type={TypeOfBike}" : "")}, demo={IsDemo}, state={State.ToString()}, location={(CurrentStation.HasValue ? $"Station {CurrentStation}" : "On the road")}.";
|
||||
return $"Id={Id}{(WheelType != null ? $", wheel(s)={WheelType}" : string.Empty)}{(TypeOfBike != null ? $", type={TypeOfBike}" : "")}, demo={IsDemo}, state={State.ToString()}, location={(!string.IsNullOrEmpty(CurrentStation) ? $"Station {CurrentStation}" : "On the road")}.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// <summary>
|
||||
/// Holds the unique id of the bike;
|
||||
/// </summary>
|
||||
int Id { get; }
|
||||
string Id { get; }
|
||||
|
||||
/// <summary> True if bike is a demo bike. </summary>
|
||||
bool IsDemo { get; }
|
||||
|
@ -37,7 +37,7 @@ namespace TINK.Model.Bike.BC
|
|||
/// <summary>
|
||||
/// Station a which bike is located, null otherwise.
|
||||
/// </summary>
|
||||
int? CurrentStation { get; }
|
||||
string CurrentStation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Uri of the operator or null, in case of single operator setup.
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace TINK.Model.Bikes.Bike.BC
|
|||
/// <summary>
|
||||
/// Holds the unique id of the bike;
|
||||
/// </summary>
|
||||
int Id { get; }
|
||||
string Id { get; }
|
||||
|
||||
/// <summary> True if bike is a demo bike. </summary>
|
||||
bool IsDemo { get; }
|
||||
|
@ -35,7 +35,7 @@ namespace TINK.Model.Bikes.Bike.BC
|
|||
/// <summary>
|
||||
/// Station a which bike is located, null otherwise.
|
||||
/// </summary>
|
||||
int? CurrentStation { get; }
|
||||
string CurrentStation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the rent state of the bike.
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace TINK.Model.Bike
|
|||
/// <param name="p_iId">Unique id of bike.</param>
|
||||
/// <param name="p_strCurrentStationName">Name of station where bike is located, null if bike is on the road.</param>
|
||||
public Bike(
|
||||
int p_iId,
|
||||
string p_iId,
|
||||
WheelType? wheelType = null,
|
||||
TypeOfBike? typeOfBike = null,
|
||||
string description = null)
|
||||
|
@ -43,7 +43,7 @@ namespace TINK.Model.Bike
|
|||
/// <summary>
|
||||
/// Holds the unique id of the bike;
|
||||
/// </summary>
|
||||
public int Id { get; }
|
||||
public string Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the count of wheels.
|
||||
|
|
|
@ -18,10 +18,10 @@ namespace TINK.Model.Bike.BluetoothLock
|
|||
/// <param name="tariffDescription">Hold tariff description of bike.</param>
|
||||
/// <param name="wheelType">Trike, two wheels, mono, ....</param>
|
||||
public BikeInfo(
|
||||
int bikeId,
|
||||
string bikeId,
|
||||
int lockId,
|
||||
Guid lockGuid,
|
||||
int? currentStationId,
|
||||
string currentStationId,
|
||||
Uri operatorUri = null,
|
||||
TariffDescription tariffDescription = null,
|
||||
bool? isDemo = DEFAULTVALUEISDEMO,
|
||||
|
@ -58,7 +58,7 @@ namespace TINK.Model.Bike.BluetoothLock
|
|||
/// <param name="p_oDateTimeNowProvider">Date time provider to calculate reaining time.</param>
|
||||
/// <param name="wheelType"></param>
|
||||
public BikeInfo(
|
||||
int id,
|
||||
string id,
|
||||
int lockId,
|
||||
Guid lockGuid,
|
||||
byte[] userKey,
|
||||
|
@ -66,7 +66,7 @@ namespace TINK.Model.Bike.BluetoothLock
|
|||
byte[] seed,
|
||||
DateTime requestedAt,
|
||||
string mailAddress,
|
||||
int? currentStationId,
|
||||
string currentStationId,
|
||||
Uri operatorUri,
|
||||
TariffDescription tariffDescription,
|
||||
Func<DateTime> dateTimeProvider,
|
||||
|
@ -106,7 +106,7 @@ namespace TINK.Model.Bike.BluetoothLock
|
|||
/// <param name="tariffDescription">Hold tariff description of bike.</param>
|
||||
/// <param name="wheelType"></param>
|
||||
public BikeInfo(
|
||||
int id,
|
||||
string id,
|
||||
int lockId,
|
||||
Guid lockGuid,
|
||||
byte[] userKey,
|
||||
|
@ -114,7 +114,7 @@ namespace TINK.Model.Bike.BluetoothLock
|
|||
byte[] seed,
|
||||
DateTime bookedAt,
|
||||
string mailAddress,
|
||||
int? currentStationId,
|
||||
string currentStationId,
|
||||
Uri operatorUri,
|
||||
TariffDescription tariffDescription = null,
|
||||
bool? isDemo = DEFAULTVALUEISDEMO,
|
||||
|
|
|
@ -5,8 +5,9 @@ namespace TINK.Model.Bikes.Bike
|
|||
/// <summary>
|
||||
/// Holds tariff info for a single bike.
|
||||
/// </summary>
|
||||
#if USCSHARP9
|
||||
public record TariffDescription
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the tariff.
|
||||
/// </summary>
|
||||
|
@ -37,4 +38,38 @@ namespace TINK.Model.Bikes.Bike
|
|||
/// </summary>
|
||||
public double MaxFeeEuroPerDay { get; init; }
|
||||
}
|
||||
#else
|
||||
public class TariffDescription
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the tariff.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of the tariff.
|
||||
/// </summary>
|
||||
public int? Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costs per hour in euro.
|
||||
/// </summary>
|
||||
public double FeeEuroPerHour { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costs of the abo per month.
|
||||
/// </summary>
|
||||
public double AboEuroPerMonth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Costs per hour in euro.
|
||||
/// </summary>
|
||||
public TimeSpan FreeTimePerSession { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Max. costs per day in euro.
|
||||
/// </summary>
|
||||
public double MaxFeeEuroPerDay { get; set; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -11,37 +11,37 @@ namespace TINK.Model.Bike
|
|||
public class BikeCollection : IBikeDictionary<BikeInfo>
|
||||
{
|
||||
/// <summary> Holds the bike dictionary object.</summary>
|
||||
private Dictionary<int, BikeInfo> BikeDictionary { get; }
|
||||
private Dictionary<string, BikeInfo> BikeDictionary { get; }
|
||||
|
||||
/// <summary>Constructs an empty bike info dictionary object.</summary>
|
||||
public BikeCollection()
|
||||
{
|
||||
BikeDictionary = new Dictionary<int, BikeInfo>();
|
||||
BikeDictionary = new Dictionary<string, BikeInfo>();
|
||||
}
|
||||
|
||||
/// <summary> Constructs a bike collection object.</summary>
|
||||
/// <param name="bikeDictionary"></param>
|
||||
public BikeCollection(Dictionary<int, BikeInfo> bikeDictionary)
|
||||
public BikeCollection(Dictionary<string, BikeInfo> bikeDictionary)
|
||||
{
|
||||
BikeDictionary = bikeDictionary ??
|
||||
throw new ArgumentNullException(nameof(bikeDictionary), "Can not construct BikeCollection object.");
|
||||
}
|
||||
|
||||
/// <summary> Gets a bike by its id.</summary>
|
||||
/// <param name="p_iId">Id of the bike to get.</param>
|
||||
/// <param name="id">Id of the bike to get.</param>
|
||||
/// <returns></returns>
|
||||
public BikeInfo GetById(int p_iId)
|
||||
public BikeInfo GetById(string id)
|
||||
{
|
||||
return BikeDictionary.FirstOrDefault(x => x.Key == p_iId).Value;
|
||||
return BikeDictionary.FirstOrDefault(x => x.Key == id).Value;
|
||||
}
|
||||
|
||||
/// <summary> Gets the count of bikes. </summary>
|
||||
public int Count => BikeDictionary.Count;
|
||||
|
||||
/// <summary> Gets if a bike with given id exists.</summary>
|
||||
/// <param name="p_iId">Id of bike.</param>
|
||||
/// <param name="id">Id of bike.</param>
|
||||
/// <returns>True if bike is contained, false otherwise.</returns>
|
||||
public bool ContainsKey(int p_iId) => BikeDictionary.Keys.Contains(p_iId);
|
||||
public bool ContainsKey(string id) => BikeDictionary.Keys.Contains(id);
|
||||
|
||||
/// <summary> Gets the enumerator. </summary>
|
||||
/// <returns>Enumerator object.</returns>
|
||||
|
|
|
@ -14,11 +14,11 @@ namespace TINK.Model
|
|||
/// <returns>BikeCollection holding bikes at given station or empty BikeCollection, if there are no bikes.</returns>
|
||||
public static BikeCollection GetAtStation(
|
||||
this BikeCollection bikesAtAnyStation,
|
||||
int? selectedStation)
|
||||
string selectedStation)
|
||||
{
|
||||
return new BikeCollection(bikesAtAnyStation?
|
||||
.Where(bike => selectedStation.HasValue && bike.CurrentStation == selectedStation.Value)
|
||||
.ToDictionary(x => x.Id) ?? new Dictionary<int, BikeInfo>());
|
||||
.Where(bike => !string.IsNullOrEmpty(selectedStation) && bike.CurrentStation == selectedStation)
|
||||
.ToDictionary(x => x.Id) ?? new Dictionary<string, BikeInfo>());
|
||||
}
|
||||
|
||||
/// <summary> Filters bikes by bike type. </summary>
|
||||
|
@ -28,7 +28,7 @@ namespace TINK.Model
|
|||
{
|
||||
return new BikeCollection(bcAndLockItBikes?
|
||||
.Where(bike => bike is Bike.BluetoothLock.BikeInfo)
|
||||
.ToDictionary(x => x.Id) ?? new Dictionary<int, BikeInfo>());
|
||||
.ToDictionary(x => x.Id) ?? new Dictionary<string, BikeInfo>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace TINK.Model.Bike
|
|||
// Update bike.
|
||||
GetById(bikeInfo.Id).State.Load(bikeInfo.State);
|
||||
|
||||
if (bikesToBeRemoved.Contains<int>(bikeInfo.Id))
|
||||
if (bikesToBeRemoved.Contains<string>(bikeInfo.Id))
|
||||
{
|
||||
// Remove list from obsolete list.
|
||||
bikesToBeRemoved.Remove(bikeInfo.Id);
|
||||
|
@ -86,20 +86,20 @@ namespace TINK.Model.Bike
|
|||
private set;
|
||||
}
|
||||
|
||||
public void SetSelectedBike(int p_intId)
|
||||
public void SetSelectedBike(string id)
|
||||
{
|
||||
SelectedBike = GetById(p_intId);
|
||||
SelectedBike = GetById(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a bike by its id.
|
||||
/// </summary>
|
||||
/// <param name="p_iId"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public BikeInfoMutable GetById(int p_iId)
|
||||
public BikeInfoMutable GetById(string id)
|
||||
{
|
||||
{
|
||||
return this.FirstOrDefault(bike => bike.Id == p_iId);
|
||||
return this.FirstOrDefault(bike => bike.Id == id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,18 +108,18 @@ namespace TINK.Model.Bike
|
|||
/// </summary>
|
||||
/// <param name="p_strKey">Key to check.</param>
|
||||
/// <returns>True if bike exists.</returns>
|
||||
public bool ContainsKey(int p_iId)
|
||||
public bool ContainsKey(string id)
|
||||
{
|
||||
return GetById(p_iId) != null;
|
||||
return GetById(id) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a bike by its id.
|
||||
/// </summary>
|
||||
/// <param name="p_iId">Id of bike to be removed.</param>
|
||||
public void RemoveById(int p_iId)
|
||||
/// <param name="id">Id of bike to be removed.</param>
|
||||
public void RemoveById(string id)
|
||||
{
|
||||
var l_oBike = GetById(p_iId);
|
||||
var l_oBike = GetById(id);
|
||||
if (l_oBike == null)
|
||||
{
|
||||
// Nothing to do if bike does not exists.
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace TINK.Model.Bike
|
|||
IEnumerable<BluetoothLock.LockInfo> locksInfo)
|
||||
{
|
||||
|
||||
var updatedBikesCollection = new Dictionary<int, BC.BikeInfo>();
|
||||
var updatedBikesCollection = new Dictionary<string, BC.BikeInfo>();
|
||||
|
||||
foreach (var bikeInfo in bikes)
|
||||
{
|
||||
|
|
|
@ -7,29 +7,29 @@ namespace TINK.Model.Bike
|
|||
/// <summary>
|
||||
/// Gets a bike by its id.
|
||||
/// </summary>
|
||||
/// <param name="p_iId"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
T GetById(int p_iId);
|
||||
T GetById(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Deteermines whether a bike by given key exists.
|
||||
/// </summary>
|
||||
/// <param name="p_strKey">Key to check.</param>
|
||||
/// <returns>True if bike exists.</returns>
|
||||
bool ContainsKey(int p_iId);
|
||||
bool ContainsKey(string id);
|
||||
}
|
||||
public interface IBikeDictionaryMutable<T> : IBikeDictionary<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes a bike by its id.
|
||||
/// </summary>
|
||||
/// <param name="p_iId">Id of bike to be removed.</param>
|
||||
void RemoveById(int p_iId);
|
||||
/// <param name="id">Id of bike to be removed.</param>
|
||||
void RemoveById(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new element to dictinary.
|
||||
/// </summary>
|
||||
/// <param name="p_oNewElement">New element to add.</param>
|
||||
void Add(T p_oNewElement);
|
||||
/// <param name="newElement">New element to add.</param>
|
||||
void Add(T newElement);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
using Serilog;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Model.Repository.Request;
|
||||
using TINK.Model.Repository.Response;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -122,7 +123,8 @@ namespace TINK.Model.Connector
|
|||
|
||||
public async Task DoReturn(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location)
|
||||
LocationDto location,
|
||||
ISmartDevice smartDevice)
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected returning request detected. No user logged in.");
|
||||
await Task.CompletedTask;
|
||||
|
@ -132,7 +134,11 @@ namespace TINK.Model.Connector
|
|||
/// Submits feedback to copri server.
|
||||
/// </summary>
|
||||
/// <param name="userFeedback">Feedback to submit.</param>
|
||||
#if USCSHARP9
|
||||
public async Task DoSubmitFeedback(ICommand.IUserFeedback userFeedback, Uri opertorUri)
|
||||
#else
|
||||
public async Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri)
|
||||
#endif
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected submit feedback request detected. No user logged in.");
|
||||
await Task.CompletedTask;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Model.Repository.Exception;
|
||||
using TINK.Model.Repository.Request;
|
||||
using TINK.Model.Repository.Response;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -30,7 +31,7 @@ namespace TINK.Model.Connector
|
|||
/// Logs user in.
|
||||
/// If log in succeeds either and session might be updated if it was no more valid (logged in by an different device).
|
||||
/// If log in fails (password modified) session cookie is set to empty.
|
||||
/// If communication fails an TINK.Model.Repository.Exception is thrown.
|
||||
/// If communication fails an TINK.Repository.Exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="p_oAccount">Account to use for login.</param>
|
||||
public Task<IAccount> DoLogin(string p_strMail, string p_strPassword, string p_strDeviceId)
|
||||
|
@ -242,12 +243,13 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
|
||||
/// <summary> Request to return a bike.</summary>
|
||||
/// <param name="latitude">Latitude of the bike.</param>
|
||||
/// <param name="longitude">Longitude of the bike.</param>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
/// <param name="locaton">Position of the bike.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
public async Task DoReturn(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location)
|
||||
LocationDto location,
|
||||
ISmartDevice smartDevice)
|
||||
{
|
||||
if (bike == null)
|
||||
{
|
||||
|
@ -257,7 +259,7 @@ namespace TINK.Model.Connector
|
|||
ReservationCancelReturnResponse l_oResponse;
|
||||
try
|
||||
{
|
||||
l_oResponse = (await CopriServer.DoReturn(bike.Id, location, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
|
||||
l_oResponse = (await CopriServer.DoReturn(bike.Id, location, smartDevice, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -272,8 +274,12 @@ namespace TINK.Model.Connector
|
|||
/// Submits feedback to copri server.
|
||||
/// </summary>
|
||||
/// <param name="userFeedback">Feedback to submit.</param>
|
||||
#if USCSHARP9
|
||||
public async Task DoSubmitFeedback(ICommand.IUserFeedback userFeedback, Uri opertorUri)
|
||||
=> await CopriServer.DoSubmitFeedback(userFeedback.Message, userFeedback.IsBikeBroken, opertorUri);
|
||||
|
||||
=> await CopriServer.DoSubmitFeedback(userFeedback.BikeId, userFeedback.Message, userFeedback.IsBikeBroken, opertorUri);
|
||||
#else
|
||||
public async Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri)
|
||||
=> await CopriServer.DoSubmitFeedback(userFeedback.BikeId, userFeedback.Message, userFeedback.IsBikeBroken, opertorUri);
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Repository.Request;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -44,9 +45,10 @@ namespace TINK.Model.Connector
|
|||
Task DoBook(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike);
|
||||
|
||||
/// <summary> Request to return a bike.</summary>
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
Task DoReturn(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto geolocation = null);
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
Task DoReturn(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto geolocation = null, ISmartDevice smartDevice = null);
|
||||
|
||||
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>
|
||||
bool IsConnected { get; }
|
||||
|
@ -55,12 +57,15 @@ namespace TINK.Model.Connector
|
|||
string SessionCookie { get; }
|
||||
|
||||
Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri);
|
||||
|
||||
#if USCSHARP9
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
public interface IUserFeedback
|
||||
{
|
||||
/// <summary> Id of the bike to which the feedback is related to.</summary>
|
||||
string BikeId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
|
@ -74,12 +79,37 @@ namespace TINK.Model.Connector
|
|||
/// </summary>
|
||||
string Message { get; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Defines delegate to be raised whenever login state changes.</summary>
|
||||
/// <param name="p_oEventArgs">Holds session cookie and mail address if user logged in successfully.</param>
|
||||
public delegate void LoginStateChangedEventHandler(object p_oSender, LoginStateChangedEventArgs p_oEventArgs);
|
||||
|
||||
#if !USCSHARP9
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
public interface IUserFeedback
|
||||
{
|
||||
/// <summary> Id of the bike to which the feedback is related to.</summary>
|
||||
string BikeId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
bool IsBikeBroken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds either
|
||||
/// - general feedback
|
||||
/// - error description of broken bike
|
||||
/// or both.
|
||||
/// </summary>
|
||||
string Message { get; }
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary> Event arguments to notify about changes of logged in state.</summary>
|
||||
public class LoginStateChangedEventArgs : EventArgs
|
||||
{
|
||||
|
|