Compare commits

...

2 commits

Author SHA1 Message Date
Anja 91d42552c7 Version 3.0.363 2023-04-19 12:14:14 +02:00
Anja 4ff3307997 Version 3.0.362 2023-04-05 15:02:10 +02:00
274 changed files with 5705 additions and 4463 deletions

17
.vsspell Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Visual Studio Spell Checker configuration file - [https://github.com/EWSoftware/VSSpellChecker]
Do not edit the XML. Use the configuration file editor in Visual Studio to modify the settings. -->
<SpellCheckerConfiguration Format="2018.8.16.0">
<InheritAdditionalDictionaryFolders>True</InheritAdditionalDictionaryFolders>
<AdditionalDictionaryFolders>
<Folder>.\\</Folder>
</AdditionalDictionaryFolders>
<SelectedLanguages />
<InheritIgnoredClassifications>True</InheritIgnoredClassifications>
<IgnoredClassifications />
<InheritIgnoredWords>True</InheritIgnoredWords>
<IgnoredWordsFile>IgnoredWords.dic</IgnoredWordsFile>
<InheritExclusionExpressions>True</InheritExclusionExpressions>
<InheritIgnoredFilePatterns>True</InheritIgnoredFilePatterns>
<InheritXmlSettings>True</InheritXmlSettings>
</SpellCheckerConfiguration>

11
IgnoredWords.dic Normal file
View file

@ -0,0 +1,11 @@
cts
Darmstadt
enum
Freiburg
haveltec
javaminister
konrad
Mein
sharee
tink
xdoc

View file

@ -77,7 +77,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.1" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="MonkeyCache">
<Version>1.6.3</Version>
@ -86,7 +86,7 @@
<Version>1.6.3</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="PInvoke.BCrypt" Version="0.7.124" />
@ -185,7 +185,7 @@
<Version>1.0.0.16</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.2.1.9</Version>
<Version>1.3.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -195,9 +195,9 @@
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<PackageReference Include="Xamarin.Forms.AppLinks">
<Version>5.0.0.2545</Version>
<Version>5.0.0.2578</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps">
<Version>5.0.0</Version>

View file

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

File diff suppressed because it is too large Load diff

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key>
<string>LastenradBayern</string>
<key>CFBundleVersion</key>
<string>361</string>
<string>363</string>
<key>CFBundleShortVersionString</key>
<string>3.0.361</string>
<string>3.0.363</string>
</dict>
</plist>

View file

@ -120,7 +120,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.Build" Version="1.0.21" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.1" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="MonkeyCache">
<Version>1.6.3</Version>
@ -129,7 +129,7 @@
<Version>1.6.3</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="Plugin.BluetoothLE">
@ -220,7 +220,7 @@
<Version>0.7.124</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms">
<Version>5.0.0.2545</Version>
<Version>5.0.0.2578</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

View file

@ -338,9 +338,9 @@ namespace TINK
/// <summary>
/// Service container to manage geolocation services.
/// </summary>
public static IServicesContainer<IGeolocation> LocationServicesContainer { get; }
= new ServicesContainerMutableT<IGeolocation>(
new HashSet<IGeolocation> {
public static IServicesContainer<IGeolocationService> LocationServicesContainer { get; }
= new ServicesContainerMutableT<IGeolocationService>(
new HashSet<IGeolocationService> {
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new GeolocationAccuracyMediumService(DependencyService.Get<IGeolodationDependent>()),

View file

@ -66,7 +66,7 @@
<Frame>
<StackLayout>
<Label FormattedText="{Binding LikeTinkApp}"/>
<!--- Mail to app- releated support -->
<!--- Mail to app- related support -->
<Button
Text="{x:Static resources:AppResources.ActionContactMailAppReleated}"
IsEnabled="{Binding IsSendMailAvailable}"

View file

@ -1,4 +1,4 @@
using System;
using System;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms.Xaml;
@ -69,7 +69,7 @@ namespace TINK.View
#endif
{
/// <summary>
/// Holds the current chargeing level of the battery entered by user in bars, null if unkonwn.
/// Holds the current charging level of the battery entered by user in bars, null if unknown.
/// </summary>
public int? CurrentChargeBars { get; set; }
@ -87,4 +87,4 @@ namespace TINK.View
public string Message { get; set; }
}
}
}
}

View file

@ -24,7 +24,7 @@
x:Name="EMailEntry"
Text="{Binding MailAddress}"
IsEnabled="{Binding IsLoggedOut}"/>
<Label Text="{x:Static resources:AppResources.MarkingLoginPasswordLabel}"/>
<Label Text="{x:Static resources:AppResources.MarkingLoginPasswordPlaceholder}"/>
<Entry
Placeholder="{x:Static resources:AppResources.MarkingLoginPasswordPlaceholder}"
AutomationId="password_text"

View file

@ -100,7 +100,7 @@ namespace TINK.View.MyBikes
{
if (m_oViewModel == null)
{
// View model might be null (Example: Occured when page to querry for location permissions was opened)
// View model might be null (Example: Occured when page to query for location permissions was opened)
return;
}

View file

@ -1,5 +1,5 @@
using System;
using TINK.Model.Station;
using System;
using TINK.Model.Stations;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
@ -9,12 +9,12 @@ using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
/// <summary>
/// Mamages creation of detail pages if a flyout page menu entry is selected.
/// Manages creation of detail pages if a flyout page menu entry is selected.
/// Exposes flyout page style navigation which is used by detail pages.
/// </summary>
/// <remarks>
/// Examples of use cases when detail pages do navigation:
// - switch to map page after succesfully logging in/ logging out
// - switch to map page after successfully logging in/ logging out
// - switch to login page form bikes at station page if not yet logged in
/// </remarks>
[XamlCompilation(XamlCompilationOptions.Compile)]
@ -29,7 +29,7 @@ namespace TINK.View.Root
InitializeComponent();
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
// Any type of split behavior conflicts with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
var navigationPage = Detail as NavigationPage;
@ -62,7 +62,7 @@ namespace TINK.View.Root
}
// Set selected station to new
App.ModelRoot.SelectedStation = new NullStation();
App.ModelRoot.SelectedStation = new TINK.Model.Stations.StationNS.NullStation();
ShowPage(item.TargetType, item.Title);
@ -92,4 +92,4 @@ namespace TINK.View.Root
Detail = new NavigationPage(page);
}
}
}
}

View file

@ -441,7 +441,7 @@ namespace TINK.Services.BluetoothLock.BLE
if (authInfo.K_seed.Length != SEEDLENGTH
|| authInfo.K_u.Length <= 0)
{
throw new AuthKeyException($"Can not authenticate. Invalid seed-/ k-user-lenght {authInfo.K_seed.Length}/ {authInfo.K_u.Length} detected.");
throw new AuthKeyException($"Can not authenticate. Invalid seed-/ k-user-length {authInfo.K_seed.Length}/ {authInfo.K_u.Length} detected.");
}
if (Device.State == Plugin.BLE.Abstractions.DeviceState.Connected)
@ -551,7 +551,7 @@ namespace TINK.Services.BluetoothLock.BLE
if (authInfo.K_seed.Length != SEEDLENGTH
|| authInfo.K_u.Length <= 0)
{
throw new AuthKeyException($"Can not authenticate. Invalid seed-/ k-user-lenght {authInfo.K_seed.Length}/ {authInfo.K_u.Length} detected.");
throw new AuthKeyException($"Can not authenticate. Invalid seed-/ k-user-length {authInfo.K_seed.Length}/ {authInfo.K_u.Length} detected.");
}
Log.ForContext<LockItBase>().Debug($"Connection state is {deviceState} in context of auth.");
@ -636,11 +636,11 @@ namespace TINK.Services.BluetoothLock.BLE
cts.CancelAfter(READ_TIMEOUT_MS);
try
{
seedLockEncrypted = await authCharacteristic.ReadAsync(cts.Token); // encrypted seed value (random value) from lock to decypt using k_user
seedLockEncrypted = await authCharacteristic.ReadAsync(cts.Token); // encrypted seed value (random value) from lock to decrypt using k_user
}
catch (System.Exception exception)
{
Log.ForContext<LockItBase>().Error("Retrieveing encrypted random value from lock (seed)(ReadAsync-call) failed.{ReadCharacteristic}{Exception}", ToSerilogString(authCharacteristic), exception);
Log.ForContext<LockItBase>().Error("Retrieving encrypted random value from lock (seed)(ReadAsync-call) failed.{ReadCharacteristic}{Exception}", ToSerilogString(authCharacteristic), exception);
throw new System.Exception(string.Format("Can not authenticate. Reading encrypted seed failed. {0}", exception.Message), exception);
}
finally
@ -648,7 +648,7 @@ namespace TINK.Services.BluetoothLock.BLE
cts.Dispose();
}
Log.ForContext<LockItBase>().Debug("Retrieveing encrypted random value from lock (seed)(ReadAsync-call) succeeded.{ReadCharacteristic}{Reading}", ToSerilogString(authCharacteristic), "***");
Log.ForContext<LockItBase>().Debug("Retrieving encrypted random value from lock (seed)(ReadAsync-call) succeeded.{ReadCharacteristic}{Reading}", ToSerilogString(authCharacteristic), "***");
var crypto = new AuthCryptoHelper(
seedLockEncrypted,
@ -701,7 +701,7 @@ namespace TINK.Services.BluetoothLock.BLE
/// <exception cref="BluetoothDisconnectedException">App is not connected to lock.</exception>
/// <exception cref="CoundntGetCharacteristicException">Getting state characteristic to read from failed.</exception>
/// <exception cref="Exception">
/// Call not from main thread or unkonwn platform detected or
/// Call not from main thread or unknown platform detected or
/// query device state (connected, disconnected, ....) failed for an unknown reason or returned an unexpected value or
/// reading state characteristic failed or reading from characteristic was empty.
/// </exception>
@ -1044,8 +1044,8 @@ namespace TINK.Services.BluetoothLock.BLE
{
ActivateLockWriteCounter--;
Log.ForContext<LockItBase>().Error(open
? "Encypting command to open lock failed. {Exception}"
: "Encypting command to close lock failed. {Exception}",
? "Encrypting command to open lock failed. {Exception}"
: "Encrypting command to close lock failed. {Exception}",
exception);
throw new System.Exception(open
? $"Can not open lock. Encrypting command to lock/ unlock failed. {exception.Message}"
@ -1251,6 +1251,6 @@ namespace TINK.Services.BluetoothLock.BLE
=> charcteristic.Id.ToString();
private static string ToSerilogString(byte[] byteArray)
=> "***"; // For debuging purposes it might be reqired to return string.Join(",", byteArray); Do not log any confidental value in production context.
=> "***"; // For debugging purposes it might be required to return string.Join(",", byteArray); Do not log any confidental value in production context.
}
}

View file

@ -162,7 +162,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Closed
// - LockitLockingState.Unknown
// - LockitLockingState.CouldntOpenBoldBlocked
// Internal error which sould never occure. Lock refuses to open but connection is ok.
// Internal error which should never occur. Lock refuses to open but connection is ok.
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Unexpected lock state {lockingState.Value.GetLockingState()} detected.");
throw new CouldntOpenInconsistentStateExecption(lockingState.Value.GetLockingState());
}
@ -280,7 +280,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Open
// - LockitLockingState.Unknown
// - LockitLockingState.CouldntOpenBoldBlocked
// Internal error which sould never occurre. Lock refuses to close but connection is ok.
// Internal error which should never occur. Lock refuses to close but connection is ok.
Log.ForContext<LockItEventBased>().Debug($"Opening lock failed. Unexpected lock state {lockingState.Value.GetLockingState()} detected.");
throw new CouldntCloseInconsistentStateExecption(lockingState.Value.GetLockingState());
}

View file

@ -128,7 +128,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Closed
// - 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.
// Internal error which should never occur. Lock refuses to open but connection is ok.
Log.ForContext<LockItPolling>().Debug($"Opening lock failed. Unexpected lock state {info.State.Value.GetLockingState()} detected.");
throw new CouldntOpenInconsistentStateExecption(info.State.Value.GetLockingState());
}
@ -235,7 +235,7 @@ namespace TINK.Services.BluetoothLock.BLE
// - LockitLockingState.Open
// - LockitLockingState.Unknown
// - LockitLockingState.CouldntOpenBoldBlocked
// Internal error which sould never occurre. Lock refuses to close but connection is ok.
// Internal error which should never occur. Lock refuses to close but connection is ok.
Log.ForContext<LockItPolling>().Debug($"Closing lock failed. Unexpected lock state {info.State.Value.GetLockingState()} detected.");
throw new CouldntCloseInconsistentStateExecption(info.State.Value.GetLockingState());
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -20,7 +20,7 @@ namespace TINK.Services.BluetoothLock.BLE
Cipher = cipher;
}
/// <summary> Holds timeout values for series of connecting attemps to a lock or multiple locks. </summary>
/// <summary> Holds timeout values for series of connecting attempts to a lock or multiple locks. </summary>
public ITimeOutProvider TimeOut { get; set; }
protected ICipher Cipher { get; }
@ -179,4 +179,4 @@ namespace TINK.Services.BluetoothLock.BLE
return LockingState.UnknownDisconnected;
}
}
}
}

View file

@ -22,7 +22,7 @@
<Folder Include="Services\BluetoothLock\Crypto\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="2.12.0" />
</ItemGroup>
<ItemGroup>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
@ -8,7 +8,7 @@ namespace TINK.Services.BluetoothLock
{
public interface ILocksService
{
/// <summary> Holds timeout values for series of connecting attemps to a lock or multiple locks. </summary>
/// <summary> Holds timeout values for series of connecting attempts to a lock or multiple locks. </summary>
ITimeOutProvider TimeOut { get; set; }
/// <summary> Gets lock info for all lock in reach./// </summary>

View file

@ -77,7 +77,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.1" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="MonkeyCache">
<Version>1.6.3</Version>
@ -86,7 +86,7 @@
<Version>1.6.3</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="PInvoke.BCrypt" Version="0.7.124" />
@ -185,7 +185,7 @@
<Version>1.0.0.16</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.2.1.9</Version>
<Version>1.3.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -195,9 +195,9 @@
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<PackageReference Include="Xamarin.Forms.AppLinks">
<Version>5.0.0.2545</Version>
<Version>5.0.0.2578</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps">
<Version>5.0.0</Version>

View file

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

File diff suppressed because it is too large Load diff

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key>
<string>Mein konrad</string>
<key>CFBundleVersion</key>
<string>361</string>
<string>363</string>
<key>CFBundleShortVersionString</key>
<string>3.0.361</string>
<string>3.0.363</string>
</dict>
</plist>

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "StationMarkerOpenBlue.svg",
"filename" : "StationMarkerOpenBlue.pdf",
"idiom" : "universal"
},
{

View file

@ -0,0 +1,69 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœm<EFBFBD>An1E÷>(c8FŽP<C5BD>”dÑ,ÒÞ_*¶‡E”j¤™ÿÌüïÅóÁñÅÇ£< a÷Ajð.~nðùEpû-ÜPIÂ÷€S[A©b8œáYJw`ÁÆ2Ü™z‰ÿNÃêð ÜQ&Å8>},nT¡zLû ¢I»ÎŒ:v•ZQ]w£]÷€ûìî<C3AC>¡2ªy,ÀŒ$=YÑ°á Ô¹Í&BÕe©%Næ6;néc:mȦ¸žšœ„LK^7•ô<E280A2>%^+þWúZ.åaqV²
endstream
endobj
5 0 obj
206
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 29.393326 37.5 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.17.4 (https://cairographics.org))
/Creator <FEFF0049006E006B0073006300610070006500200031002E0031002E00320020002800680074007400700073003A002F002F0069006E006B00730063006100700065002E006F007200670029>
/CreationDate (D:20230323095234+01'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000617 00000 n
0000000392 00000 n
0000000320 00000 n
0000000015 00000 n
0000000298 00000 n
0000000682 00000 n
0000000965 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1017
%%EOF

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "StationMarkerOpenGreen.svg",
"filename" : "StationMarkerOpenGreen.pdf",
"idiom" : "universal"
},
{

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "StationMarkerOpenLightBlue.svg",
"filename" : "StationMarkerOpenLightBlue.pdf",
"idiom" : "universal"
},
{

View file

@ -0,0 +1,69 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœm<EFBFBD>An1E÷>(c8FŽP<C5BD>”dÑ,ÒÞ_*¶‡E”j¤™ÿÌüïÅóÁñÅÇ£< a÷Ajð.~nðùEpû-ÜPIÂ÷€S[A©b8œáYJw`ÁÆ2Ü™z‰ÿNÃêð ÜQ&Å8>},nT¡zLû ¢I»ÎŒ:v•ZQ]w£]÷€ûìî<C3AC>¡2ªy,ÀŒ$=YÑ°á Ô¹Í&BÕe©%Næ6;néc:mȦ¸žšœ„LK^7•ô<E280A2>%^+þWúZ.åaqV²
endstream
endobj
5 0 obj
206
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 29.393326 37.5 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.17.4 (https://cairographics.org))
/Creator <FEFF0049006E006B0073006300610070006500200031002E0031002E00320020002800680074007400700073003A002F002F0069006E006B00730063006100700065002E006F007200670029>
/CreationDate (D:20230323095234+01'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000617 00000 n
0000000392 00000 n
0000000320 00000 n
0000000015 00000 n
0000000298 00000 n
0000000682 00000 n
0000000965 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1017
%%EOF

View file

@ -1,7 +1,7 @@
{
"images" : [
{
"filename" : "StationMarkerOpenRed.svg",
"filename" : "StationMarkerOpenRed.pdf",
"idiom" : "universal"
},
{

View file

@ -0,0 +1,69 @@
%PDF-1.5
%µí®û
4 0 obj
<< /Length 5 0 R
/Filter /FlateDecode
>>
stream
xœm<EFBFBD>An1E÷>(c8FŽP<C5BD>”dÑ,ÒÞ_*¶‡E”j¤™ÿÌüïÅóÁñÅÇ£< a÷Ajð.~nðùEpû-ÜPIÂ÷€S[A©b8œáYJw`ÁÆ2Ü™z‰ÿNÃêð ÜQ&Å8>},nT¡zLû ¢I»ÎŒ:v•ZQ]w£]÷€ûìî<C3AC>¡2ªy,ÀŒ$=YÑ°á Ô¹Í&BÕe©%Næ6;néc:mȦ¸žšœ„LK^7•ô<E280A2>%^+þWúZ.åaqV²
endstream
endobj
5 0 obj
206
endobj
3 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
2 0 obj
<< /Type /Page % 1
/Parent 1 0 R
/MediaBox [ 0 0 29.393326 37.5 ]
/Contents 4 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 3 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 2 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Producer (cairo 1.17.4 (https://cairographics.org))
/Creator <FEFF0049006E006B0073006300610070006500200031002E0031002E00320020002800680074007400700073003A002F002F0069006E006B00730063006100700065002E006F007200670029>
/CreationDate (D:20230323095234+01'00)
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000617 00000 n
0000000392 00000 n
0000000320 00000 n
0000000015 00000 n
0000000298 00000 n
0000000682 00000 n
0000000965 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1017
%%EOF

View file

@ -121,7 +121,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.Build" Version="1.0.21" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.1" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="MonkeyCache">
<Version>1.6.3</Version>
@ -130,7 +130,7 @@
<Version>1.6.3</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="Plugin.BluetoothLE">
@ -221,7 +221,7 @@
<Version>0.7.124</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms">
<Version>5.0.0.2545</Version>
<Version>5.0.0.2578</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
@ -294,25 +294,25 @@
<ImageAsset Include="Media.xcassets\LaunchImages.launchimage\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_Blue.imageset\StationMarkerOpenBlue.svg">
<ImageAsset Include="Media.xcassets\Open_Blue.imageset\StationMarkerOpenBlue.pdf">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_Blue.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_Green.imageset\StationMarkerOpenGreen.svg">
<ImageAsset Include="Media.xcassets\Open_Green.imageset\StationMarkerOpenGreen.pdf">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_Green.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_LightBlue.imageset\StationMarkerOpenLightBlue.svg">
<ImageAsset Include="Media.xcassets\Open_LightBlue.imageset\StationMarkerOpenLightBlue.pdf">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_LightBlue.imageset\Contents.json">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_Red.imageset\StationMarkerOpenRed.svg">
<ImageAsset Include="Media.xcassets\Open_Red.imageset\StationMarkerOpenRed.pdf">
<Visible>false</Visible>
</ImageAsset>
<ImageAsset Include="Media.xcassets\Open_Red.imageset\Contents.json">

View file

@ -30,6 +30,13 @@
<!--Arrow down from line-->
<x:String x:Key="ArrowDown">&#xf063;</x:String>
<!--Info in Circle-->
<x:String x:Key="InfoCircle">&#xf05a;</x:String>
<!--AaAbRideType-->
<x:String x:Key="LocationPin">&#xf3c5;</x:String>
<x:String x:Key="ArrowReturnBack">&#xf0e2;</x:String>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->

View file

@ -336,9 +336,9 @@ namespace TINK
/// <summary>
/// Service container to manage geolocation services.
/// </summary>
public static IServicesContainer<IGeolocation> LocationServicesContainer { get; }
= new ServicesContainerMutableT<IGeolocation>(
new HashSet<IGeolocation> {
public static IServicesContainer<IGeolocationService> LocationServicesContainer { get; }
= new ServicesContainerMutableT<IGeolocationService>(
new HashSet<IGeolocationService> {
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new GeolocationAccuracyMediumService(DependencyService.Get<IGeolodationDependent>()),

View file

@ -12,6 +12,7 @@
<ContentView.Resources>
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
</ContentView.Resources>
<Frame
Padding="10"
Margin="0,5,0,5"
@ -23,75 +24,157 @@
Orientation="Vertical"
Padding="10">
<!-- Icons, Name, ID -->
<Grid Padding="0,0,5,10"
<!-- Icons, Name, ID, ... -->
<Grid
Padding="0"
RowSpacing="15"
ColumnSpacing="5"
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto">
RowDefinitions="Auto,Auto,Auto">
<!-- Icon of the bike -->
<!-- Bike image -->
<Image
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"
HorizontalOptions="Start"
VerticalOptions="End"/>
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"/>
<!-- Battery level -->
<!-- Battery level image -->
<sharedGui:BarLevelView
Grid.Column="1"
Grid.Row="1"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
VerticalOptions="End"
IsVisible="{Binding IsBatteryChargeVisible}"/>
Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
IsVisible="{Binding IsBatteryChargeVisible}"/>
<!-- Name of the bike -->
<Label
<!-- Rental state and error -->
<StackLayout
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="2"
Spacing="0"
Orientation="Vertical"
HorizontalOptions="Start"
VerticalOptions="End">
<!-- Rental state -->
<Label
Text="{Binding StateText}"
FontSize="Small"
TextColor="{Binding StateColor}"/>
<!-- Rental state error info -->
<Label
Text="{Binding ErrorText}"
FontSize="Small"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
</StackLayout>
<!-- Name and Id of the bike -->
<StackLayout
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="0"
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
Orientation="Vertical"
VerticalOptions="Start"
HorizontalOptions="End"
Spacing="0">
<!-- Id of the bike -->
<Label
<!-- Name -->
<Label
FontAttributes="Bold"
FontSize="Large"
TextColor="Black"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
<!-- Id -->
<Label
TextColor="DimGray"
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
</StackLayout>
<!-- AaAbRideType -->
<StackLayout
Grid.Column="2"
Grid.Row="1"
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
Grid.RowSpan="2"
Spacing="0"
HorizontalOptions="End"
VerticalOptions="End"
IsVisible="{Binding AaRideType}">
<StackLayout
Orientation="Horizontal"
HorizontalOptions="End">
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource LocationPin}"
Color="Black"
FontFamily="FA-S"
Size="20"/>
</Image.Source>
</Image>
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource ArrowReturnBack}"
Color="Black"
FontFamily="FA-S"
Size="20"/>
</Image.Source>
</Image>
<Button
Command="{Binding ShowRideTypeInfoCommand}"
WidthRequest="24"
HeightRequest="24"
BackgroundColor="Transparent"
BorderWidth="0"
Padding="0"
Margin="5,0,0,0">
<Button.ImageSource>
<FontImageSource
Glyph="{StaticResource InfoCircle}"
Color="DimGray"
FontFamily="FA-S"
Size="20"/>
</Button.ImageSource>
</Button>
</StackLayout>
<Label
Text= "{Binding StationId}"
FontSize="Small"
HorizontalOptions="End"/>
</StackLayout>
</Grid>
<!-- Rental state -->
<Label
Text="{Binding StateText}"
TextColor="{Binding StateColor}"/>
<Label
Text="{Binding ErrorText}"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
<!-- Buttons -->
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
Command="{Binding OnButtonClicked}"/>
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
Command="{Binding OnButtonClicked}"/>
<Button
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
Command="{Binding OnLockitButtonClicked}"/>
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
Command="{Binding OnLockitButtonClicked}"/>
<!-- Rental description (tarif name, options and rental info -->
<Grid
RowSpacing="0"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
RowSpacing="0"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
<Grid.RowDefinitions>
<!-- start tarif- entries -->
<RowDefinition Height="Auto" />
@ -115,19 +198,52 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Text= "{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionTariffHeader}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
FontAttributes="Bold"/>
Text= "{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionTariffHeader}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
FontAttributes="Bold"/>
<Label
Text="{Binding TariffDescription.Header}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
Grid.Column="1"
FontAttributes="Bold"/>
Text="{Binding TariffDescription.Header}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
Grid.Column="1"
FontAttributes="Bold"/>
<!--Tracking-->
<Grid
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
ColumnDefinitions="*,Auto"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}">
<Label
Text= "Tracking"
Grid.Column="0"
HorizontalOptions="End"/>
<Button
Command="{Binding ShowTrackingInfoCommand}"
WidthRequest="24"
HeightRequest="24"
BackgroundColor="Transparent"
BorderWidth="0"
Grid.Column="1"
Padding="0"
Margin="0">
<Button.ImageSource>
<FontImageSource
Glyph="{StaticResource InfoCircle}"
Color="DimGray"
FontFamily="FA-S"
Size="20"/>
</Button.ImageSource>
</Button>
</Grid>
<Label
Text= "{Binding TariffDescription.TarifEntry1.Description}"
IsVisible="{Binding TariffDescription.TarifEntry1.Description, Converter={StaticResource Label_Converter}}"
@ -136,7 +252,8 @@
Text="{Binding TariffDescription.TarifEntry1.Value}"
IsVisible="{Binding TariffDescription.TarifEntry1.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="1"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry2.Description}"
IsVisible="{Binding TariffDescription.TarifEntry2.Description, Converter={StaticResource Label_Converter}}"
@ -145,7 +262,8 @@
Text="{Binding TariffDescription.TarifEntry2.Value}"
IsVisible="{Binding TariffDescription.TarifEntry2.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="2"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry3.Description}"
IsVisible="{Binding TariffDescription.TarifEntry3.Description, Converter={StaticResource Label_Converter}}"
@ -154,7 +272,8 @@
Text="{Binding TariffDescription.TarifEntry3.Value}"
IsVisible="{Binding TariffDescription.TarifEntry3.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="3"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry4.Description}"
IsVisible="{Binding TariffDescription.TarifEntry4.Description, Converter={StaticResource Label_Converter}}"
@ -163,7 +282,8 @@
Text="{Binding TariffDescription.TarifEntry4.Value}"
IsVisible="{Binding TariffDescription.TarifEntry4.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="4"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry5.Description}"
IsVisible="{Binding TariffDescription.TarifEntry5.Description, Converter={StaticResource Label_Converter}}"
@ -172,7 +292,8 @@
Text="{Binding TariffDescription.TarifEntry5.Value}"
IsVisible="{Binding TariffDescription.TarifEntry5.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="5"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry6.Description}"
IsVisible="{Binding TariffDescription.TarifEntry6.Description, Converter={StaticResource Label_Converter}}"
@ -181,7 +302,8 @@
Text="{Binding TariffDescription.TarifEntry6.Value}"
IsVisible="{Binding TariffDescription.TarifEntry6.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="6"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry7.Description}"
IsVisible="{Binding TariffDescription.TarifEntry7.Description, Converter={StaticResource Label_Converter}}"
@ -190,7 +312,8 @@
Text="{Binding TariffDescription.TarifEntry7.Value}"
IsVisible="{Binding TariffDescription.TarifEntry7.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="7"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry8.Description}"
IsVisible="{Binding TariffDescription.TarifEntry8.Description, Converter={StaticResource Label_Converter}}"
@ -199,7 +322,8 @@
Text="{Binding TariffDescription.TarifEntry8.Value}"
IsVisible="{Binding TariffDescription.TarifEntry8.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="8"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TarifEntry9.Description}"
IsVisible="{Binding TariffDescription.TarifEntry9.Description, Converter={StaticResource Label_Converter}}"
@ -208,33 +332,29 @@
Text="{Binding TariffDescription.TarifEntry9.Value}"
IsVisible="{Binding TariffDescription.TarifEntry9.Value, Converter={StaticResource Label_Converter}}"
Grid.Row="9"
Grid.Column="1"/>
Grid.Column="1"
Grid.ColumnSpan="2"/>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Text= "{Binding TariffDescription.InfoEntry1}"
IsVisible="{Binding TariffDescription.InfoEntry1, Converter={StaticResource Label_Converter}}"
Grid.Row="10"
Grid.ColumnSpan="2"/>
Grid.ColumnSpan="3"/>
<Label
Text= "{Binding TariffDescription.InfoEntry2}"
IsVisible="{Binding TariffDescription.InfoEntry2, Converter={StaticResource Label_Converter}}"
Grid.Row="11"
Grid.ColumnSpan="2"/>
Grid.ColumnSpan="3"/>
<Label
Text= "{Binding TariffDescription.InfoEntry3}"
IsVisible="{Binding TariffDescription.InfoEntry3, Converter={StaticResource Label_Converter}}"
Grid.Row="12"
Grid.ColumnSpan="2"/>
Grid.ColumnSpan="3"/>
<Label
Text= "{Binding TariffDescription.InfoEntry4}"
IsVisible="{Binding TariffDescription.InfoEntry4, Converter={StaticResource Label_Converter}}"
Grid.Row="13"
Grid.ColumnSpan="2"/>
<Label
Text= "{Binding TariffDescription.TrackingInfoText}"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}"
Grid.Row="14"
Grid.ColumnSpan="2"/>
Grid.ColumnSpan="3"/>
</Grid>
</StackLayout>
</Frame>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:conv="clr-namespace:TINK.View"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
@ -68,7 +68,7 @@
<Frame>
<StackLayout>
<Label FormattedText="{Binding LikeTinkApp}"/>
<!--- Mail to app- releated support -->
<!--- Mail to app- related support -->
<Button
Text="{x:Static resources:AppResources.ActionContactMailAppReleated}"
IsEnabled="{Binding IsSendMailAvailable}"
@ -90,4 +90,4 @@
</Frame>
</ScrollView>
</ContentPage.Content>
</ContentPage>
</ContentPage>

View file

@ -1,4 +1,4 @@
using System;
using System;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms.Xaml;
@ -70,7 +70,7 @@ namespace TINK.View
#endif
{
/// <summary>
/// Holds the current chargeing level of the battery entered by user in bars, null if unkonwn.
/// Holds the current charging level of the battery entered by user in bars, null if unknown.
/// </summary>
public int? CurrentChargeBars { get; set; }
@ -88,4 +88,4 @@ namespace TINK.View
public string Message { get; set; }
}
}
}
}

View file

@ -43,7 +43,6 @@
WidthRequest="320"
HeightRequest="800"
x:Name="MyMap"
MyLocationEnabled="True"
MapType="Street">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>

View file

@ -31,9 +31,6 @@ namespace TINK.View.Map
public MapPage()
{
InitializeComponent();
MyMap.UiSettings.MyLocationButtonEnabled = true;
}
/// <summary>
@ -211,6 +208,24 @@ namespace TINK.View.Map
isInitializationStarted = false;
return;
}
try
{
Log.ForContext<MapPage>().Verbose("Setting map settings.");
//show current user position (blue dot) and enable button for centering map manually.
MyMap.UiSettings.MyLocationButtonEnabled = MapPageViewModel.IsLocationPermissionGranted;
MyMap.IsShowingUser = MapPageViewModel.IsLocationPermissionGranted;
//disable +/- buttons
MyMap.UiSettings.ZoomControlsEnabled = false;
}
catch (Exception exception)
{
Log.ForContext<MapPage>().Verbose("Setting map settings failed. {Exception}", exception);
isInitializationStarted = false;
return;
}
}
/// <summary>

View file

@ -100,7 +100,7 @@ namespace TINK.View.MyBikes
{
if (m_oViewModel == null)
{
// View model might be null (Example: Occured when page to querry for location permissions was opened)
// View model might be null (Example: Occured when page to query for location permissions was opened)
return;
}

View file

@ -1,5 +1,5 @@
using System;
using TINK.Model.Station;
using System;
using TINK.Model.Stations;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
@ -9,12 +9,12 @@ using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
/// <summary>
/// Mamages creation of detail pages if a flyout page menu entry is selected.
/// Manages creation of detail pages if a flyout page menu entry is selected.
/// Exposes flyout page style navigation which is used by detail pages.
/// </summary>
/// <remarks>
/// Examples of use cases when detail pages do navigation:
// - switch to map page after succesfully logging in/ logging out
// - switch to map page after successfully logging in/ logging out
// - switch to login page form bikes at station page if not yet logged in
/// </remarks>
[XamlCompilation(XamlCompilationOptions.Compile)]
@ -29,7 +29,7 @@ namespace TINK.View.Root
InitializeComponent();
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
// Any type of split behavior conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
var navigationPage = Detail as NavigationPage;
@ -62,7 +62,7 @@ namespace TINK.View.Root
}
// Set selected station to new
App.ModelRoot.SelectedStation = new NullStation();
App.ModelRoot.SelectedStation = new TINK.Model.Stations.StationNS.NullStation();
ShowPage(item.TargetType, item.Title);
@ -92,4 +92,4 @@ namespace TINK.View.Root
Detail = new NavigationPage(page);
}
}
}
}

View file

@ -46,6 +46,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D5B69C6F-3413-4773-923E-21A65B21C3A3}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.vsspell = .vsspell
EndProjectSection
EndProject
Global

View file

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

File diff suppressed because it is too large Load diff

View file

@ -77,7 +77,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.1" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="MonkeyCache">
<Version>1.6.3</Version>
@ -86,7 +86,7 @@
<Version>1.6.3</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="PInvoke.BCrypt" Version="0.7.124" />
@ -185,7 +185,7 @@
<Version>1.0.0.16</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.2.1.9</Version>
<Version>1.3.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -195,9 +195,9 @@
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2545" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<PackageReference Include="Xamarin.Forms.AppLinks">
<Version>5.0.0.2545</Version>
<Version>5.0.0.2578</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps">
<Version>5.0.0</Version>

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key>
<string>sharee.bike</string>
<key>CFBundleVersion</key>
<string>361</string>
<string>363</string>
<key>CFBundleShortVersionString</key>
<string>3.0.361</string>
<string>3.0.363</string>
</dict>
</plist>

View file

@ -121,7 +121,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.Build" Version="1.0.21" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.0" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="7.0.1" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="MonkeyCache">
<Version>1.6.3</Version>
@ -130,7 +130,7 @@
<Version>1.6.3</Version>
</PackageReference>
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="Plugin.BluetoothLE">
@ -221,7 +221,7 @@
<Version>0.7.124</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms">
<Version>5.0.0.2545</Version>
<Version>5.0.0.2578</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

View file

@ -32,7 +32,11 @@
<!--Info in Circle-->
<x:String x:Key="InfoCircle">&#xf05a;</x:String>
<!--AaAbRideType-->
<x:String x:Key="LocationPin">&#xf3c5;</x:String>
<x:String x:Key="ArrowReturnBack">&#xf0e2;</x:String>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->

View file

@ -345,9 +345,9 @@ namespace TINK
/// <summary>
/// Service container to manage geolocation services.
/// </summary>
public static IServicesContainer<IGeolocation> LocationServicesContainer { get; }
= new ServicesContainerMutableT<IGeolocation>(
new HashSet<IGeolocation> {
public static IServicesContainer<IGeolocationService> LocationServicesContainer { get; }
= new ServicesContainerMutableT<IGeolocationService>(
new HashSet<IGeolocationService> {
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new GeolocationAccuracyMediumService(DependencyService.Get<IGeolodationDependent>()),

View file

@ -25,77 +25,158 @@
Orientation="Vertical"
Padding="10">
<!-- Icons, Name, ID -->
<Grid Padding="0,0,5,10"
<!-- Icons, Name, ID, ... -->
<Grid
Padding="0"
RowSpacing="15"
ColumnSpacing="5"
ColumnDefinitions="Auto,Auto,*"
RowDefinitions="Auto,Auto">
RowDefinitions="Auto,Auto,Auto">
<!-- Icon of the bike -->
<!-- Bike image -->
<Image
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"
HorizontalOptions="Start"
VerticalOptions="End"/>
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"/>
<!-- Battery level -->
<!-- Battery level image -->
<sharedGui:BarLevelView
Grid.Column="1"
Grid.Row="1"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
VerticalOptions="End"
IsVisible="{Binding IsBatteryChargeVisible}"/>
Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
IsVisible="{Binding IsBatteryChargeVisible}"/>
<!-- Name of the bike -->
<Label
<!-- Rental state and error -->
<StackLayout
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="2"
Spacing="0"
Orientation="Vertical"
HorizontalOptions="Start"
VerticalOptions="End">
<!-- Rental state -->
<Label
Text="{Binding StateText}"
FontSize="Small"
TextColor="{Binding StateColor}"/>
<!-- Rental state error info -->
<Label
Text="{Binding ErrorText}"
FontSize="Small"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
</StackLayout>
<!-- Name and Id of the bike -->
<StackLayout
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="0"
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
Orientation="Vertical"
VerticalOptions="Start"
HorizontalOptions="End"
Spacing="0">
<!-- Name -->
<Label
FontAttributes="Bold"
FontSize="Large"
TextColor="Black"
HorizontalTextAlignment="Right"
Text="{Binding Name}"/>
<!-- Id of the bike -->
<Label
<!-- Id -->
<Label
TextColor="DimGray"
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
</StackLayout>
<!-- AaAbRideType -->
<StackLayout
Grid.Column="2"
Grid.Row="1"
FontAttributes="Bold"
HorizontalTextAlignment="Right"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
Grid.RowSpan="2"
Spacing="0"
HorizontalOptions="End"
VerticalOptions="End"
IsVisible="{Binding AaRideType}">
<StackLayout
Orientation="Horizontal"
HorizontalOptions="End">
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource LocationPin}"
Color="Black"
FontFamily="FA-S"
Size="20"/>
</Image.Source>
</Image>
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource ArrowReturnBack}"
Color="Black"
FontFamily="FA-S"
Size="20"/>
</Image.Source>
</Image>
<Button
Command="{Binding ShowRideTypeInfoCommand}"
WidthRequest="24"
HeightRequest="24"
BackgroundColor="Transparent"
BorderWidth="0"
Padding="0"
Margin="5,0,0,0">
<Button.ImageSource>
<FontImageSource
Glyph="{StaticResource InfoCircle}"
Color="DimGray"
FontFamily="FA-S"
Size="20"/>
</Button.ImageSource>
</Button>
</StackLayout>
<Label
Text= "{Binding StationId}"
FontSize="Small"
HorizontalOptions="End"/>
</StackLayout>
</Grid>
<!-- Rental state -->
<Label
Text="{Binding StateText}"
TextColor="{Binding StateColor}"/>
<Label
Text="{Binding ErrorText}"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
<!-- Buttons -->
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
Command="{Binding OnButtonClicked}"/>
<Button
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
Command="{Binding OnLockitButtonClicked}"/>
<!-- Buttons -->
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
Command="{Binding OnButtonClicked}"/>
<Button
Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
Command="{Binding OnLockitButtonClicked}"/>
<!-- Rental description (tarif name, options and rental info -->
<Grid
RowSpacing="0"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
<Grid.RowDefinitions>
<!-- Rental description (tarif name, options and rental info -->
<Grid
RowSpacing="0"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
<Grid.RowDefinitions>
<!-- start tarif- entries -->
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@ -113,59 +194,58 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Text= "{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionTariffHeader}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
FontAttributes="Bold"/>
<Label
Text="{Binding TariffDescription.Header}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
Grid.Column="1"
FontAttributes="Bold"/>
<!--Tracking-->
<Grid
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
ColumnDefinitions="*,Auto"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}">
<Label
Text= "Tracking"
FontAttributes="Bold"
Grid.Column="0"
HorizontalOptions="End"/>
<Button
Command="{Binding ShowTrackingInfoCommand}"
WidthRequest="24"
HeightRequest="24"
BackgroundColor="Transparent"
BorderWidth="0"
<!-- start tarif- entries (should be a CollectionView) -->
<Label
Text= "{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionTariffHeader}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
FontAttributes="Bold"/>
<Label
Text="{Binding TariffDescription.Header}"
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}"
Grid.Row="0"
Grid.Column="1"
Padding="0"
Margin="0">
<Button.ImageSource>
<FontImageSource
Glyph="{StaticResource InfoCircle}"
Color="DimGray"
FontFamily="FA-S"
Size="20"/>
</Button.ImageSource>
</Button>
</Grid>
FontAttributes="Bold"/>
<!--Tracking-->
<Grid
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
ColumnDefinitions="*,Auto"
IsVisible="{Binding TariffDescription.TrackingInfoText, Converter={StaticResource Label_Converter}}">
<Label
Text= "Tracking"
Grid.Column="0"
HorizontalOptions="End"/>
<Button
Command="{Binding ShowTrackingInfoCommand}"
WidthRequest="24"
HeightRequest="24"
BackgroundColor="Transparent"
BorderWidth="0"
Grid.Column="1"
Padding="0"
Margin="0">
<Button.ImageSource>
<FontImageSource
Glyph="{StaticResource InfoCircle}"
Color="DimGray"
FontFamily="FA-S"
Size="20"/>
</Button.ImageSource>
</Button>
</Grid>
<Label
Text= "{Binding TariffDescription.TarifEntry1.Description}"
IsVisible="{Binding TariffDescription.TarifEntry1.Description, Converter={StaticResource Label_Converter}}"
Grid.Row="1"/>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:conv="clr-namespace:TINK.View"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
@ -67,7 +67,7 @@
<Frame>
<StackLayout>
<Label FormattedText="{Binding LikeTinkApp}"/>
<!--- Mail to app- releated support -->
<!--- Mail to app- related support -->
<Button
Text="{x:Static resources:AppResources.ActionContactMailAppReleated}"
IsEnabled="{Binding IsSendMailAvailable}"
@ -89,4 +89,4 @@
</Frame>
</ScrollView>
</ContentPage.Content>
</ContentPage>
</ContentPage>

View file

@ -1,4 +1,4 @@
using System;
using System;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms.Xaml;
@ -69,7 +69,7 @@ namespace TINK.View
#endif
{
/// <summary>
/// Holds the current chargeing level of the battery entered by user in bars, null if unkonwn.
/// Holds the current charging level of the battery entered by user in bars, null if unknown.
/// </summary>
public int? CurrentChargeBars { get; set; }
@ -87,4 +87,4 @@ namespace TINK.View
public string Message { get; set; }
}
}
}
}

View file

@ -41,7 +41,6 @@
WidthRequest="320"
HeightRequest="800"
x:Name="MyMap"
MyLocationEnabled="True"
MapType="Street">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>

View file

@ -31,9 +31,6 @@ namespace TINK.View.Map
public MapPage()
{
InitializeComponent();
MyMap.UiSettings.MyLocationButtonEnabled = true;
}
/// <summary>
@ -211,6 +208,25 @@ namespace TINK.View.Map
isInitializationStarted = false;
return;
}
try
{
Log.ForContext<MapPage>().Verbose("Setting map settings.");
//show current user position (blue dot) and enable button for centering map manually.
MyMap.UiSettings.MyLocationButtonEnabled = MapPageViewModel.IsLocationPermissionGranted;
MyMap.IsShowingUser = MapPageViewModel.IsLocationPermissionGranted;
//disable +/- buttons
MyMap.UiSettings.ZoomControlsEnabled = false;
}
catch (Exception exception)
{
Log.ForContext<MapPage>().Verbose("Setting map settings failed. {Exception}", exception);
isInitializationStarted = false;
return;
}
}
/// <summary>

View file

@ -100,7 +100,7 @@ namespace TINK.View.MyBikes
{
if (m_oViewModel == null)
{
// View model might be null (Example: Occured when page to querry for location permissions was opened)
// View model might be null (Example: Occured when page to query for location permissions was opened)
return;
}

View file

@ -1,5 +1,5 @@
using System;
using TINK.Model.Station;
using System;
using TINK.Model.Stations;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
@ -9,12 +9,12 @@ using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
/// <summary>
/// Mamages creation of detail pages if a flyout page menu entry is selected.
/// Manages creation of detail pages if a flyout page menu entry is selected.
/// Exposes flyout page style navigation which is used by detail pages.
/// </summary>
/// <remarks>
/// Examples of use cases when detail pages do navigation:
// - switch to map page after succesfully logging in/ logging out
// - switch to map page after successfully logging in/ logging out
// - switch to login page form bikes at station page if not yet logged in
/// </remarks>
[XamlCompilation(XamlCompilationOptions.Compile)]
@ -29,7 +29,7 @@ namespace TINK.View.Root
InitializeComponent();
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
// Any type of split behavior conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
var navigationPage = Detail as NavigationPage;
@ -62,7 +62,7 @@ namespace TINK.View.Root
}
// Set selected station to new
App.ModelRoot.SelectedStation = new NullStation();
App.ModelRoot.SelectedStation = new TINK.Model.Stations.StationNS.NullStation();
ShowPage(item.TargetType, item.Title);
@ -92,4 +92,4 @@ namespace TINK.View.Root
Detail = new NavigationPage(page);
}
}
}
}

View file

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Serilog;
using TINK.Model.Station;
using TINK.Model.Stations.StationNS;
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
using BikeInfoMutable = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable;
@ -25,7 +25,7 @@ namespace TINK.Model.Bikes
/// </summary>
/// <param name="bikesAll"> Object holding bikes info from copri to update from. Holds station id but not station name.</param>
/// <param name="stations"> All stations to get station names from.</param>
/// <param name="p_oDateTimeProvider">Provices date time information.</param>
/// <param name="p_oDateTimeProvider">Provides date time information.</param>
public void Update(
IEnumerable<BikeInfo> bikesAll,
IEnumerable<IStation> stations)
@ -74,18 +74,18 @@ namespace TINK.Model.Bikes
}
/// <summary>
/// Adds a new bike to collecion of bike.
/// Adds a new bike to collection of bike.
/// </summary>
/// <param name="newBike">New bike to add.</param>
/// <exception cref="Exception">Thrown if bike is not unique.</exception>
public new void Add(BikeInfoMutable newBike)
{
// Ensure that bike id of new bike is is unique
// Ensure that bike id of new bike is unique
foreach (BikeInfoMutable bike in Items)
{
if (bike.Id == newBike.Id)
{
throw new Exception(string.Format("Can not add bike with {0} to collection ob bike. Id is not unnique.", newBike));
throw new Exception(string.Format("Can not add bike with {0} to collection ob bike. Id is not unique.", newBike));
}
}
@ -93,7 +93,7 @@ namespace TINK.Model.Bikes
}
/// <summary>
/// Bike selected by user for regerving or cancel reservation.
/// Bike selected by user for reserving or cancel reservation.
/// </summary>
public BikeInfoMutable SelectedBike
{
@ -115,7 +115,7 @@ namespace TINK.Model.Bikes
=> this.FirstOrDefault(bike => bike.Id == id);
/// <summary>
/// Deteermines whether a bike by given key exists.
/// Determines whether a bike by given key exists.
/// </summary>
/// <param name="p_strKey">Key to check.</param>
/// <returns>True if bike exists.</returns>

View file

@ -6,7 +6,7 @@ using TINK.Model.State;
namespace TINK.Model.Bikes.BikeInfoNS.BC
{
public class BikeInfo : IBikeInfo
public abstract class BikeInfo : IBikeInfo
{
/// <summary> Default value of demo property. </summary>
public const bool DEFAULTVALUEISDEMO = false;
@ -64,72 +64,6 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
bikeInfo.TariffDescription)
{ }
/// <summary>
/// Constructs a bike info object for a available bike.
/// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="stationId">Id of station where bike is located.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param>
public BikeInfo(
Bike bike,
Drive drive,
DataSource dataSource,
string stationId,
Uri operatorUri = null,
RentalDescription tariffDescription = null,
bool? isDemo = DEFAULTVALUEISDEMO,
IEnumerable<string> group = null) : this(
new StateInfo(),
bike,
drive,
dataSource,
isDemo,
group,
stationId,
operatorUri,
tariffDescription)
{
}
/// <summary>
/// Constructs a bike info object for a booked bike.
/// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
/// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param>
/// <param name="bookedAt">Date time when bike was booked</param>
/// <param name="mailAddress">Mail address of user which booked bike.</param>
/// <param name="code">Booking code.</param>
public BikeInfo(
Bike bike,
Drive drive,
DataSource dataSource,
bool? isDemo,
IEnumerable<string> group,
string currentStationId,
Uri operatorUri,
RentalDescription tariffDescription,
DateTime bookedAt,
string mailAddress,
string code) : this(
new StateInfo(
bookedAt,
mailAddress,
code),
bike,
drive,
dataSource,
isDemo,
group,
currentStationId,
operatorUri,
tariffDescription)
{
}
/// <summary> True if device is demo device, false otherwise. </summary>
public bool IsDemo { get; }
@ -141,7 +75,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary>
public string StationId { get; }
/// <summary> Holds description about the tarif. </summary>
/// <summary> Holds description about the tariff. </summary>
public RentalDescription TariffDescription { get; }
/// Holds the rent state of the bike.

View file

@ -9,7 +9,7 @@ using TINK.Model.State;
namespace TINK.Model.Bikes.BikeInfoNS.BC
{
[DataContract]
public class BikeInfoMutable : IBikeInfoMutable, INotifyPropertyChanged
public abstract class BikeInfoMutable : IBikeInfoMutable, INotifyPropertyChanged
{
/// <summary> Holds the bike. </summary>
private readonly Bike _Bike;
@ -24,7 +24,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// Constructs a bike.
/// </summary>
/// <param name="isDemo">True if device is demo device, false otherwise.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remaining time on demand for state of type reserved.</param>
/// <param name="stationId">Name of station where bike is located, null if bike is on the road.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param>
@ -55,24 +55,6 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
TariffDescription = tariffDescription;
}
/// <summary> Constructs a bike object from source. </summary>
public BikeInfoMutable(IBikeInfo bike, string stationName) : this(
bike != null
? bike.Bike
: throw new ArgumentNullException(nameof(bike)),
bike.Drive,
bike.DataSource,
bike.IsDemo,
bike.Group,
bike.StationId,
stationName,
bike.OperatorUri,
bike.TariffDescription,
null /* date time provider */,
bike.State)
{
}
/// <summary> Id of station a which bike is located, null otherwise.</summary>
[DataMember]
public string StationId { get; }
@ -81,7 +63,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
[DataMember]
public string StationName { get; }
/// <summary> Holds description about the tarif. </summary>
/// <summary> Holds description about the tariff. </summary>
[DataMember]
public RentalDescription TariffDescription { get; private set; }
@ -113,6 +95,12 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
public TypeOfBike? TypeOfBike => _Bike.TypeOfBike;
/// <summary>
/// Gets whether bike is a AA bike (bike must be always returned a the same station) or AB bike (start and end stations can be different stations).
/// </summary>
public AaRideType? AaRideType => _Bike.AaRideType;
public LockModel LockModel => _Bike.LockModel;
public string Description => _Bike.Description;

View file

@ -30,6 +30,11 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary>
TypeOfBike? TypeOfBike { get; }
/// <summary>
/// Gets whether bike is a AA bike (bike must be always returned a the same station) or AB bike (start and end stations can be different stations).
/// </summary>
AaRideType? AaRideType { get; }
/// <summary> Gets the model of the lock. </summary>
LockModel LockModel { get; }

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
namespace TINK.Model.Bikes.BikeInfoNS.BikeNS
@ -21,12 +21,19 @@ namespace TINK.Model.Bikes.BikeInfoNS.BikeNS
City = 2,
}
/// <summary> Holds whether bike is a AA bike (bike must be always returned a the same station) or AB bike (start and end stations can be different stations).</summary>
public enum AaRideType
{
NoAaRide = 0,
AaRide = 1,
}
/// <summary> Holds the model of lock. </summary>
public enum LockModel
{
ILockIt, // haveltec GbmH Brandenburg, Germany bluetooth lock
BordComputer, // Teilrad BC
Sigo, // Sigo Gmbh Darmstadt, Germany bike lock
BordComputer, // TeilRad BC
Sigo, // Sigo GmbH Darmstadt, Germany bike lock
}
/// <summary> Holds the type of lock. </summary>
@ -47,10 +54,12 @@ namespace TINK.Model.Bikes.BikeInfoNS.BikeNS
LockModel lockModel,
WheelType? wheelType = null,
TypeOfBike? typeOfBike = null,
AaRideType? aaRideType = null,
string description = null)
{
WheelType = wheelType;
TypeOfBike = typeOfBike;
AaRideType = aaRideType;
LockModel = lockModel;
Id = id;
Description = description;
@ -71,6 +80,11 @@ namespace TINK.Model.Bikes.BikeInfoNS.BikeNS
/// </summary>
public TypeOfBike? TypeOfBike { get; }
/// <summary>
/// Gets whether bike is a AA bike (bike must be always returned a the same station) or AB bike (start and end stations can be different stations).
/// </summary>
public AaRideType? AaRideType { get; }
/// <summary> Gets the model of the lock. </summary>
public LockModel LockModel { get; private set; }

View file

@ -33,9 +33,10 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
bike != null
? new Bike(
bike.Id,
LockModel.ILockIt /* Ensure consistend lock model value */,
LockModel.ILockIt /* Ensure consistent lock model value */,
bike.WheelType,
bike.TypeOfBike,
bike.AaRideType,
bike.Description)
: throw new ArgumentNullException(nameof(bike)),
drive,
@ -53,7 +54,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
/// Constructs a bike info object for a requested bike.
/// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remaining time on demand for state of type reserved.</param>
/// <param name="lockId">Id of the lock.</param>
/// <param name="lockGuid">GUID specifying the lock.</param>
/// <param name="requestedAt">Date time when bike was requested</param>
@ -61,7 +62,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
/// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param>
/// <param name="dateTimeProvider">Date time provider to calculate reaining time.</param>
/// <param name="dateTimeProvider">Date time provider to calculate remaining time.</param>
public BikeInfo(
Bike bike,
Drive drive,
@ -87,9 +88,10 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
bike != null
? new Bike(
bike.Id,
LockModel.ILockIt /* Ensure consistend lock model value */,
LockModel.ILockIt /* Ensure consistent lock model value */,
bike.WheelType,
bike.TypeOfBike,
bike.AaRideType,
bike.Description)
: throw new ArgumentNullException(nameof(bike)),
drive,
@ -139,9 +141,10 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
bike != null
? new Bike(
bike.Id,
LockModel.ILockIt /* Ensure consistend lock model value */,
LockModel.ILockIt /* Ensure consistent lock model value */,
bike.WheelType,
bike.TypeOfBike,
bike.AaRideType,
bike.Description)
: throw new ArgumentNullException(),
drive,
@ -155,7 +158,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
LockInfo = new LockInfo.Builder { Id = lockId, Guid = lockGuid, UserKey = userKey, AdminKey = adminKey, Seed = seed }.Build();
}
public BikeInfo(Model.Bikes.BikeInfoNS.BC.BikeInfo bikeInfo, LockInfo lockInfo) : base(
public BikeInfo(BC.BikeInfo bikeInfo, LockInfo lockInfo) : base(
bikeInfo ?? throw new ArgumentException($"Can not copy-construct {typeof(BikeInfo).Name}-object. Source bike info must not be null."))
{
LockInfo = lockInfo

View file

@ -1,6 +1,6 @@
namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
{
public interface IBikeInfoMutable : BikeInfoNS.BC.IBikeInfoMutable
public interface IBikeInfoMutable : BC.IBikeInfoMutable
{
ILockInfoMutable LockInfo { get; }
}

View file

@ -1,4 +1,5 @@
using System;
using TINK.Services.Geolocation;
namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
{
@ -20,6 +21,14 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
byte[] Seed { get; }
/// <summary> Timestamp of the last locking state change.</summary>
DateTime? LastLockingStateChange { get; }
/// <summary>
/// Gets or sets the current location of the bike, null if location is unknown.
/// </summary>
IGeolocation Location { get; set; }
/// <summary>
/// Gets the version info of the locks.
/// </summary>

View file

@ -1,4 +1,5 @@
using System;
using TINK.Services.Geolocation;
namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
{
@ -7,16 +8,24 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
/// <summary> Lock info object. </summary>
private LockInfo LockInfo { get; set; }
/// <summary>
/// Delegate to create time stamp.
/// </summary>
private Func<DateTime> _nowDelegate;
/// <summary> Constructs a bluetooth lock info object. </summary>
/// <param name="id">Id of lock must always been known when constructing an lock info object.</param>
/// <param name="nowDelegate">Delegate to create time stamp if null DateTime.Now is used.</param>
public LockInfoMutable(
int id,
Guid guid,
byte[] userKey,
byte[] adminKey,
byte[] seed,
LockingState state)
LockingState state,
Func<DateTime> nowDelegate = null)
{
_nowDelegate = nowDelegate ?? (() => DateTime.Now);
LockInfo = new LockInfo.Builder() { Id = id, Guid = guid, UserKey = userKey, AdminKey = adminKey, Seed = seed, State = state }.Build();
}
@ -35,12 +44,34 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
public byte[] AdminKey => LockInfo.AdminKey;
/// <summary>
/// Gets or sets the locking state.
/// </summary>
public LockingState State
{
get => LockInfo.State;
set => LockInfo = new LockInfo.Builder(LockInfo) { State = value }.Build();
set
{
if (LockInfo.State == value)
{
// State does not change, nothing to do.
return;
}
Location = null; // Invalidate location.
LastLockingStateChange = _nowDelegate(); // Get time stamp when state change happened.
LockInfo = new LockInfo.Builder(LockInfo) { State = value }.Build();
}
}
/// <summary> Gets the timestamp of the last locking state change.</summary>
public DateTime? LastLockingStateChange { get; private set; }
/// <summary>
/// Gets or sets the current location of the bike, null if location is unknown.
/// </summary>
public IGeolocation Location { get; set; }
/// <summary> Holds the percentage of lock battery.</summary>
public double BatteryPercentage { get; set; } = double.NaN;

View file

@ -38,8 +38,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
? new Bike(
bike.Id,
LockModel.Sigo,
bike.WheelType /* Ensure consistend lock model value */,
bike.WheelType /* Ensure consistent lock model value */,
bike.TypeOfBike,
bike.AaRideType,
bike.Description)
: throw new ArgumentNullException(nameof(bike)),
drive,
@ -66,7 +67,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
/// <param name="lockInfo">Lock info.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remaining time on demand for state of type reserved.</param>
public BikeInfo(
Bike bike,
Drive drive,
@ -88,9 +89,10 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
bike != null
? new Bike(
bike.Id,
LockModel.Sigo /* Ensure consistend lock model value */,
LockModel.Sigo /* Ensure consistent lock model value */,
bike.WheelType,
bike.TypeOfBike,
bike.AaRideType,
bike.Description)
: throw new ArgumentNullException(nameof(bike)),
drive,
@ -136,9 +138,10 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
bike != null
? new Bike(
bike.Id,
LockModel.Sigo /* Ensure consistend lock model value */,
LockModel.Sigo /* Ensure consistent lock model value */,
bike.WheelType,
bike.TypeOfBike,
bike.AaRideType,
bike.Description)
: throw new ArgumentNullException(nameof(bike)),
drive,

View file

@ -35,7 +35,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
return;
}
// Add a dummy querry. Querries are not yet read from COPRI but compiled into the app.
// Add a dummy query. Querries are not yet read from COPRI but compiled into the app.
BookingFinishedModel.MiniSurvey.Questions.Add("q1", new MiniSurvey.QuestionModel());
}

View file

@ -1,4 +1,4 @@
using Serilog;
using Serilog;
namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
{
@ -12,12 +12,12 @@ namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
public double CurrentChargePercent { get; private set; } = double.NaN;
/// <summary>
/// Holds the current chargeing level of the battery in bars, null if unkonwn.
/// Holds the current charging level of the battery in bars, null if unknown.
/// </summary>
public int? CurrentChargeBars { get; private set; } = null;
/// <summary>
/// Holds the maximum chargeing level of the battery in bars, null if unkonwn.
/// Holds the maximum charging level of the battery in bars, null if unknown.
/// </summary>
public int? MaxChargeBars { get; private set; } = null;
@ -34,12 +34,12 @@ namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
public class Builder
{
/// <summary>
/// Holds the current chargeing level of the battery in bars.
/// Holds the current charging level of the battery in bars.
/// </summary>
public int? CurrentChargeBars { get; set; } = null;
/// <summary>
/// Holds the maximum chargeing level of the battery in bars.
/// Holds the maximum charging level of the battery in bars.
/// </summary>
public int? MaxChargeBars { get; set; } = null;
@ -83,7 +83,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
&& MaxChargeBars == null)
{
// If current charge bars is set, max charge must be set as well.
Log.ForContext<Battery>().Error($"Current bars value can not be set to {CurrentChargeBars} if max bars is not se.");
Log.ForContext<Battery>().Error($"Current bars value can not be set to {CurrentChargeBars} if max bars is not set.");
CurrentChargeBars = null;
}
@ -92,7 +92,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
&& CurrentChargeBars > MaxChargeBars)
{
// If current charge bars must never be larger than max charge bars.
Log.ForContext<Battery>().Error($"Invalid current bars value {CurrentChargeBars} detected. Value must never be largen than max value bars {MaxChargeBars}.");
Log.ForContext<Battery>().Error($"Invalid current bars value {CurrentChargeBars} detected. Value must never be larger than max value bars {MaxChargeBars}.");
CurrentChargeBars = null;
}

View file

@ -1,4 +1,4 @@

namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
{
public interface IBattery
@ -9,12 +9,12 @@ namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
double CurrentChargePercent { get; }
/// <summary>
/// Holds the current chargeing level of the battery in bars. Must not be arger than MaxChargeBars, null if unkonwn.
/// Holds the current charging level of the battery in bars. Must not be larger than MaxChargeBars, null if unknown.
/// </summary>
int? CurrentChargeBars { get; }
/// <summary>
/// Holds the maximum chargeing level of the battery in bars, null if unkonwn.
/// Holds the maximum charging level of the battery in bars, null if unknown.
/// </summary>
int? MaxChargeBars { get; }

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace TINK.Model.Bikes
{
@ -12,7 +12,7 @@ namespace TINK.Model.Bikes
T GetById(string id);
/// <summary>
/// Deteermines whether a bike by given key exists.
/// Determines whether a bike by given key exists.
/// </summary>
/// <param name="p_strKey">Key to check.</param>
/// <returns>True if bike exists.</returns>
@ -27,7 +27,7 @@ namespace TINK.Model.Bikes
void RemoveById(string id);
/// <summary>
/// Adds a new element to dictinary.
/// Adds a new element to dictionary.
/// </summary>
/// <param name="newElement">New element to add.</param>
void Add(T newElement);

View file

@ -129,7 +129,7 @@ namespace TINK.Model.Connector
string BikeId { get; }
/// <summary>
/// Holds the current chargeing level of the battery in bars, null if unkonwn.
/// Holds the current charging level of the battery in bars, null if unknown.
/// </summary>
int? CurrentChargeBars { get; set; }

View file

@ -1,4 +1,4 @@

namespace TINK.Model.Connector
{
#if USCSHARP9
@ -18,7 +18,7 @@ namespace TINK.Model.Connector
public string BikeId { get; set; }
/// <summary>
/// Holds the current chargeing level of the battery in bars, null if unkonwn.
/// Holds the current charging level of the battery in bars, null if unknown.
/// </summary>
public int? CurrentChargeBars { get; set; }

View file

@ -1,17 +1,17 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TINK.Model.Bikes;
using TINK.Model.Connector.Filter;
using TINK.Model.Services.CopriApi;
using TINK.Model.Station;
using TINK.Model.Stations;
using TINK.Model.Stations.StationNS;
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector
{
/// <summary> Filters connector respones.</summary>
/// <summary> Filters connector responses.</summary>
/// <remarks>Former name: Filter</remarks>
public class FilteredConnector : IFilteredConnector
{
@ -50,7 +50,7 @@ namespace TINK.Model.Connector
/// <summary> Holds the filter. </summary>
private IGroupFilter Filter { get; }
/// <summary> Holds the reference to object which performs copry queries.</summary>
/// <summary> Holds the reference to object which performs copri queries.</summary>
private IQuery m_oInnerQuery;
/// <summary> Constructs a query object.</summary>
@ -111,7 +111,7 @@ namespace TINK.Model.Connector
return bikes.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary(x => x.Id);
}
/// <summary> Filter stations by broup. </summary>
/// <summary> Filter stations by group. </summary>
/// <returns></returns>
private static Dictionary<string, IStation> DoFilter(StationDictionary stations, IGroupFilter filter)
{

View file

@ -1,16 +1,16 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TINK.Model.Bikes;
using TINK.Model.Services.CopriApi;
using TINK.Model.Station;
using TINK.Model.Stations;
using TINK.Model.Stations.StationNS;
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector
{
/// <summary> Filters connector respones.</summary>
/// <summary> Filters connector responses.</summary>
public class NullFilterConnector : IFilteredConnector
{
/// <summary> Constructs a filter object. </summary>
@ -44,7 +44,7 @@ namespace TINK.Model.Connector
/// <summary> Object to perform filtered queries.</summary>
private class QueryProvider : IQuery
{
/// <summary> Holds the reference to object which performs copry queries.</summary>
/// <summary> Holds the reference to object which performs copri queries.</summary>
private IQuery m_oInnerQuery;
/// <summary> Constructs a query object.</summary>
@ -100,7 +100,7 @@ namespace TINK.Model.Connector
return bikes.Where(x => x.Group.Intersect(filter).Count() > 0).ToDictionary(x => x.Id);
}
/// <summary> Filter stations by broup. </summary>
/// <summary> Filter stations by group. </summary>
/// <returns></returns>
public static Dictionary<string, IStation> DoFilter(StationDictionary stations, IEnumerable<string> p_oFilter)
{

View file

@ -29,7 +29,7 @@ namespace TINK.Model.Connector
}
}
/// <summary> Gets all stations including postions and bikes.</summary>
/// <summary> Gets all stations including positions and bikes.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var resultStations = await server.GetStations();
@ -73,7 +73,7 @@ namespace TINK.Model.Connector
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occupied detected. No user is logged in.");
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),

View file

@ -29,7 +29,7 @@ namespace TINK.Model.Connector
}
}
/// <summary> Gets all stations including postions.</summary>
/// <summary> Gets all stations including positions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationsResponse = await Server.GetStations();

View file

@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using TINK.Model.Bikes;
using TINK.Model.Services.CopriApi;
@ -6,7 +6,7 @@ namespace TINK.Model.Connector
{
public interface IQuery
{
/// <summary> Gets all stations including postions.</summary>
/// <summary> Gets all stations including positions.</summary>
Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync();
/// <summary> Gets bikes occupied is a user is logged in. </summary>

View file

@ -28,7 +28,7 @@ namespace TINK.Model.Connector
}
}
/// <summary> Gets all stations including postions.</summary>
/// <summary> Gets all stations including positions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationsAllResponse = await server.GetStationsAsync();
@ -44,7 +44,7 @@ namespace TINK.Model.Connector
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{
Log.ForContext<Query>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
Log.ForContext<Query>().Error("Unexpected call to get be bikes occupied detected. No user is logged in.");
return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore),
await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())),

View file

@ -30,7 +30,7 @@ namespace TINK.Model.Connector
server = copriServer as ICopriServer;
}
/// <summary> Gets all stations including postions.</summary>
/// <summary> Gets all stations including positions.</summary>
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
{
var stationResponse = await server.GetStationsAsync();

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@ -9,6 +9,7 @@ using TINK.Model.Services.CopriApi.ServerUris;
using TINK.Model.State;
using TINK.Repository.Exception;
using TINK.Repository.Response;
using TINK.Repository.Response.Stations.Station;
namespace TINK.Model.Connector
{
@ -26,7 +27,7 @@ namespace TINK.Model.Connector
/// </summary>
/// <param name="stationInfo">Object to get information from.</param>
/// <returns>Position information.</returns>
public static IPosition GetPosition(this StationsAvailableResponse.StationInfo stationInfo)
public static IPosition GetPosition(this StationInfo stationInfo)
=> GetPosition(stationInfo.gps);
/// <summary> Gets the position from StationInfo object. </summary>
@ -52,14 +53,14 @@ namespace TINK.Model.Connector
if (group == null || group.Length == 0)
{
// If not logged in stations groups are empty form COPRI version v4.1.
Log.Debug("Can not get goup form string. Group text can not be null.");
Log.Debug("Can not get group form string. Group text can not be null.");
return new List<string>();
}
return new HashSet<string>(group).ToList();
}
/// <summary> Gets if user acknowldged ags or not. </summary>
/// <summary> Gets if user acknowledged AGBs or not. </summary>
/// <param name="authorizationResponse">Object to get information from.</param>
/// <returns>Position information.</returns>
public static bool GetIsAgbAcknowledged(this AuthorizationResponse authorizationResponse)
@ -77,7 +78,7 @@ namespace TINK.Model.Connector
/// <summary> Gets the position from StationInfo object. </summary>
/// <param name="stationInfo">Object to get information from.</param>
/// <returns>Position information.</returns>
public static IEnumerable<string> GetGroup(this StationsAvailableResponse.StationInfo stationInfo)
public static IEnumerable<string> GetGroup(this StationInfo stationInfo)
{
try
{
@ -297,8 +298,19 @@ namespace TINK.Model.Connector
? typeOfBike
: (TypeOfBike?)null;
/// <summary>
/// Gets whether bike is a AA bike (bike must be always returned a the same station) or AB bike (start and end stations can be different stations).
/// </summary>
/// <param name="bikeInfo">Object to get AA info from.</param>
/// <returns>AA info.</returns>
public static AaRideType? GetAaRideType(this BikeInfoBase bikeInfo)
=> Enum.TryParse(bikeInfo?.aa_ride, true, out AaRideType aaRide)
? aaRide
: (AaRideType?)null;
/// <summary> Get position from a ,- separated string. </summary>
/// <param name="gps">Text to extract positon from.</param>
/// <param name="gps">Text to extract position from.</param>
/// <returns>Position object.</returns>
public static IPosition GetPosition(Repository.Response.Position gps)
=> PositionFactory.Create(
@ -306,7 +318,7 @@ namespace TINK.Model.Connector
double.TryParse(gps?.longitude, NumberStyles.Float, CultureInfo.InvariantCulture, out double longitude) ? longitude : double.NaN);
/// <summary> Get position from a ,- separated string. </summary>
/// <param name="gps">Text to extract positon from.</param>
/// <param name="gps">Text to extract position from.</param>
/// <returns>Position object.</returns>
public static Map.IMapSpan GetMapSpan(this MapSpan mapSpan)
=> Map.MapSpanFactory.Create(
@ -343,7 +355,7 @@ namespace TINK.Model.Connector
/// Gets the operator Uri from response.
/// </summary>
/// <param name="bikeInfo"> Response to get uri from.</param>
/// <returns>Operatore Uri</returns>
/// <returns>Operator Uri</returns>
public static Uri GetOperatorUri(this BikeInfoBase bikeInfo)
{
return bikeInfo?.uri_operator != null && !string.IsNullOrEmpty(bikeInfo?.uri_operator)
@ -351,7 +363,7 @@ namespace TINK.Model.Connector
: null;
}
/// <summary> Tries to get the copriversion from response.</summary>
/// <summary> Tries to get the copri version from response.</summary>
/// <param name="response">Response to get version info from.</param>
/// <returns>COPRI version</returns>
public static bool TryGetCopriVersion(this CopriVersion response, out Version copriVersion)
@ -362,7 +374,7 @@ namespace TINK.Model.Connector
&& Version.TryParse(response.copri_version, out copriVersion);
}
/// <summary> Gets the copriversion from.</summary>
/// <summary> Gets the copri version from.</summary>
/// <param name="response">Response to get version info from.</param>
/// <returns>COPRI version</returns>
public static Version GetCopriVersion(this CopriVersion response)

View file

@ -7,7 +7,6 @@ using TINK.Model.MiniSurvey;
using TINK.Model.State;
using TINK.Repository.Response;
using BikeExtension = TINK.Model.Bikes.BikeInfoNS.BikeNS.BikeExtension;
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector.Updater
{
@ -63,7 +62,7 @@ namespace TINK.Model.Connector.Updater
var lockType = lockModel.HasValue
? BikeExtension.GetLockType(lockModel.Value)
: BikeExtension.GetLockType(DEFAULTLOCKMODEL); // Map bikes without "system"- entry in response to backend- locks.
: BikeExtension.GetLockType(DEFAULTLOCKMODEL); // Map bikes without "system"- entry in response to back end- locks.
try
{
@ -76,6 +75,7 @@ namespace TINK.Model.Connector.Updater
LockModel.Sigo,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.GetAaRideType(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
@ -94,7 +94,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetGroup(),
miniSurvey: bikeInfo.user_miniquery != null
? new MiniSurveyModel(new Dictionary<string, IQuestionModel> {
{ "q1", new QuestionModel()} // Add a dummy querry. Querries are not yet read from COPRI but compiled into the app.
{ "q1", new QuestionModel()} // Add a dummy query. Queries are not yet read from COPRI but compiled into the app.
})
: new MiniSurveyModel(),
co2Saving: bikeInfo.co2saving);
@ -106,6 +106,7 @@ namespace TINK.Model.Connector.Updater
LockModel.ILockIt,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.GetAaRideType(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
@ -129,7 +130,7 @@ namespace TINK.Model.Connector.Updater
}
catch (ArgumentException ex)
{
// Contructor reported invalid arguemts (missing lock id, ....).
// Constructor reported invalid arguments (missing lock id, ....).
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. Invalid response detected. Available bike with id {bikeInfo.bike} skipped. {ex.Message}");
return null;
}
@ -184,6 +185,7 @@ namespace TINK.Model.Connector.Updater
LockModel.ILockIt,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.GetAaRideType(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
@ -214,6 +216,7 @@ namespace TINK.Model.Connector.Updater
LockModel.Sigo,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.GetAaRideType(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
@ -238,7 +241,7 @@ namespace TINK.Model.Connector.Updater
}
catch (ArgumentException ex)
{
// Contructor reported invalid arguemts (missing lock id, ....).
// Constructor reported invalid arguments (missing lock id, ....).
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoReservedOrBooked)} argument. Invalid response detected. Reserved bike with id {bikeInfo.bike} skipped. {ex.Message}");
return null;
}
@ -255,6 +258,7 @@ namespace TINK.Model.Connector.Updater
LockModel.ILockIt,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.GetAaRideType(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
@ -278,29 +282,8 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetGroup());
case LockModel.BordComputer:
return new BikeInfo(
new Bike(
bikeInfo.bike,
LockModel.BordComputer,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
bikeInfo.GetIsDemo(),
bikeInfo.GetGroup(),
bikeInfo.station,
bikeInfo.GetOperatorUri(),
#if !NOTARIFFDESCRIPTION
bikeInfo.rental_description != null
? RentalDescriptionFactory.Create(bikeInfo.rental_description)
: TariffDescriptionFactory.Create(bikeInfo.tariff_description),
#else
Create((TINK.Repository.Response.TariffDescription)null),
#endif
bikeInfo.GetFrom(),
mailAddress,
bikeInfo.timeCode);
throw new NotSupportedException($"Bikes with lock model of type {lockModel} are no more supported.");
default:
return new Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike(
@ -308,6 +291,7 @@ namespace TINK.Model.Connector.Updater
LockModel.Sigo,
bikeInfo.GetWheelType(),
bikeInfo.GetTypeOfBike(),
bikeInfo.GetAaRideType(),
bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type),
DataSource.Copri,

View file

@ -1,17 +1,14 @@
using System;
using System.Collections.Generic;
using Serilog;
using TINK.Model.Bikes;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.State;
using TINK.Model.Station;
using TINK.Model.Station.Operator;
using TINK.Model.Stations;
using TINK.Model.Stations.StationNS.Operator;
using TINK.Model.User.Account;
using TINK.Repository.Exception;
using TINK.Repository.Response;
using TINK.Repository.Response.Stations;
using TINK.Services.CopriApi;
using Xamarin.Forms;
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
using IBikeInfoMutable = TINK.Model.Bikes.BikeInfoNS.BC.IBikeInfoMutable;
namespace TINK.Model.Connector.Updater
@ -31,7 +28,7 @@ namespace TINK.Model.Connector.Updater
=> bike.State.Load(InUseStateEnum.Disposable, notifyLevel: notifyLevel);
/// <summary>
/// Gets all statsion for station provider and add them into station list.
/// Gets all station for station provider and add them into station list.
/// </summary>
/// <param name="p_oStationList">List of stations to update.</param>
public static StationDictionary GetStationsAllMutable(this StationsAvailableResponse stationsAllResponse)
@ -57,7 +54,7 @@ namespace TINK.Model.Connector.Updater
string.Format("Station id {0} is not unique.", station.Value.station), stationsAllResponse);
}
stations.Add(new Station.Station(
stations.Add(new Stations.StationNS.Station(
station.Value.station,
station.Value.GetGroup(),
station.Value.GetPosition(),
@ -89,7 +86,7 @@ namespace TINK.Model.Connector.Updater
new ResourceUrls(response.tariff_info_html, response.bike_info_html, response.agb_html, response.privacy_html, response.impress_html));
/// <summary> Gets account object from login response.</summary>
/// <param name="merchantId">Needed to extract cookie from autorization response.</param>
/// <param name="merchantId">Needed to extract cookie from authorization response.</param>
/// <param name="loginResponse">Response to get session cookie and debug level from.</param>
/// <param name="mail">Mail address needed to construct a complete account object (is not part of response).</param>
/// <param name="password">Password needed to construct a complete account object (is not part of response).</param>

View file

@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.Collections.Generic;
using TINK.Model.Connector;
using TINK.ViewModel.Map;
using TINK.ViewModel.Settings;
namespace TINK.Model
{
/// <summary> Holds collecion of filters to filter options (TINK, Konrad, ....). </summary>
/// <summary> Holds collection of filters to filter options (TINK, Konrad, ....). </summary>
/// <remarks> Former name: FilterCollection.</remarks>
public static class GroupFilterHelper
{

View file

@ -1,7 +1,10 @@
using System;
using System;
namespace TINK.Model
{
/// <summary>
/// Holds a exact position.
/// </summary>
public interface IPosition : IEquatable<IPosition>
{
double Latitude { get; }

View file

@ -7,7 +7,7 @@ using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi.ServerUris;
using TINK.Model.Settings;
using TINK.Model.Station;
using TINK.Model.Stations.StationNS;
using TINK.Services;
using TINK.Services.BluetoothLock;
using TINK.Settings;
@ -46,15 +46,15 @@ namespace TINK.Model
/// <summary> Name of the station which is selected. </summary>
IStation SelectedStation { get; set; }
/// <summary>Polling periode.</summary>
/// <summary>Polling period.</summary>
PollingParameters Polling { get; set; }
TimeSpan ExpiresAfter { get; set; }
/// <summary> Holds status about whants new page. </summary>
/// <summary> Holds status about whats new page. </summary>
WhatsNew WhatsNew { get; }
/// <summary> Gets whether device is connected to internet or not. </summary>
/// <summary> Gets whether device is connected to Internet or not. </summary>
bool GetIsConnected();
/// <summary> Action to post to GUI thread.</summary>
@ -69,7 +69,7 @@ namespace TINK.Model
/// <summary>Settings determining the startup behavior of the app.</summary>
IStartupSettings StartupSettings { get; }
/// <summary> Value indicating whether map is centerted to current position or not. </summary>
/// <summary> Value indicating whether map is centered to current position or not. </summary>
bool CenterMapToCurrentLocation { get; set; }
/// <summary> Holds the map area where user is or was located or null if position is unknown. </summary>
@ -98,7 +98,7 @@ namespace TINK.Model
/// <summary> Holds the different lock service implementations.</summary>
LocksServicesContainerMutable LocksServices { get; }
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or Lastenrad Bayern.</summary>
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or LastenRad Bayern.</summary>
AppFlavor Flavor { get; }
/// <summary> Holds available app themes.</summary>
@ -113,7 +113,7 @@ namespace TINK.Model
/// <summary> Holds the external path. </summary>
string ExternalFolder { get; }
/// <summary> Holds the stations availalbe. </summary>
/// <summary> Holds the stations centered. </summary>
IEnumerable<IStation> Stations { get; set; }
/// <summary> Holds the Urs to query resources from. </summary>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
@ -25,7 +25,7 @@ namespace TINK.Model.Logging
if (directoryExistsChecker == null)
{
throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory existance checker delegate can not be null.");
throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory existence checker delegate can not be null.");
}
if (directoryCreator == null)
@ -42,7 +42,7 @@ namespace TINK.Model.Logging
if (string.IsNullOrEmpty(directorySeparatorChar.ToString()))
{
throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory separtor character can not be null or empty.");
throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory separator character can not be null or empty.");
}
if (p_iRetainedFilesCountLimit < 1)

View file

@ -1,9 +1,9 @@

namespace TINK.Model
{
public class NullPostion : IPosition
public class NullPosition : IPosition
{
internal NullPostion() { }
internal NullPosition() { }
public double Latitude => double.NaN;

View file

@ -6,6 +6,6 @@ namespace TINK.Model
public static IPosition Create(double latitude = double.NaN, double longitude = double.NaN)
=> Position.GetIsValid(longitude, latitude)
? new Position(latitude, longitude) as IPosition
: new NullPostion();
: new NullPosition();
}
}

View file

@ -194,7 +194,7 @@ namespace TINK.Model.Settings
}
/// <summary> Sets whether polling is on or off and the periode if polling is on. </summary>
/// <summary> Sets whether polling is on or off and the period if polling is on. </summary>
/// <param name="settingsJSON">Dictionary to write entries to.</param>
public static Dictionary<string, string> SetPollingParameters(
this IDictionary<string, string> targetDictionary,
@ -210,19 +210,19 @@ namespace TINK.Model.Settings
}).ToDictionary(key => key.Key, value => value.Value);
}
/// <summary> Get whether polling is on or off and the periode if polling is on. </summary>
/// <summary> Get whether polling is on or off and the period if polling is on. </summary>
/// <param name="settingsJSON">Dictionary holding parameters from JSON.</param>
/// <returns>Polling parameters.</returns>
public static PollingParameters GetPollingParameters(this IDictionary<string, string> settingsJSON)
{
// Check if dictionary contains entry for periode.
if (settingsJSON.TryGetValue($"{typeof(PollingParameters).Name}_{typeof(TimeSpan).Name}", out string periode)
// Check if dictionary contains entry for period.
if (settingsJSON.TryGetValue($"{typeof(PollingParameters).Name}_{typeof(TimeSpan).Name}", out string period)
&& settingsJSON.TryGetValue($"{typeof(PollingParameters).Name}_{typeof(bool).Name}", out string active)
&& !string.IsNullOrEmpty(periode)
&& !string.IsNullOrEmpty(period)
&& !string.IsNullOrEmpty(active))
{
return new PollingParameters(
JsonConvert.DeserializeObject<TimeSpan>(periode),
JsonConvert.DeserializeObject<TimeSpan>(period),
JsonConvert.DeserializeObject<bool>(active));
}
@ -409,7 +409,7 @@ namespace TINK.Model.Settings
return targetDictionary.Union(new Dictionary<string, string>
{
{ typeof(IGeolocation).Name, activeGeolocationService },
{ typeof(IGeolocationService).Name, activeGeolocationService },
}).ToDictionary(key => key.Key, value => value.Value);
}
@ -419,7 +419,7 @@ namespace TINK.Model.Settings
public static string GetActiveGeolocationService(this IDictionary<string, string> settingsJSON)
{
// Get uri of corpi server.
if (!settingsJSON.TryGetValue(typeof(IGeolocation).Name, out string activeGeolocationService)
if (!settingsJSON.TryGetValue(typeof(IGeolocationService).Name, out string activeGeolocationService)
|| string.IsNullOrEmpty(activeGeolocationService))
{
// File holds no entry.

View file

@ -16,15 +16,15 @@ namespace TINK.Settings
false);
/// <summary> Constructs a polling parameter object. </summary>
/// <param name="periode">Polling periode.</param>
/// <param name="period">Polling period.</param>
/// <param name="activated">True if polling is activated.</param>
public PollingParameters(TimeSpan periode, bool activated)
public PollingParameters(TimeSpan period, bool activated)
{
Periode = periode; // Can not be null because is a struct.
Periode = period; // Can not be null because is a struct.
IsActivated = activated;
}
/// <summary>Holds the polling periode.</summary>
/// <summary>Holds the polling period.</summary>
public TimeSpan Periode { get; }
/// <summary> Holds value whether polling is activated or not.</summary>

View file

@ -18,7 +18,7 @@ namespace TINK.Model.Settings
public const bool DEFAULTREPOTLEVEL = false;
/// <summary> Gets the type of the default geolocation service. </summary>
/// <remarks> Swtiched from GeolocationService (GeolocationAccuracyMediumService) to GeolocationAccuracyHighService in app version 3.0.290.</remarks>
/// <remarks> Switched from GeolocationService (GeolocationAccuracyMediumService) to GeolocationAccuracyHighService in app version 3.0.290.</remarks>
public static Type DefaultLocationService => typeof(GeolocationAccuracyHighService);
// Default value of the expires after entry. Controls the expiration time of the cache values.
@ -54,8 +54,8 @@ namespace TINK.Model.Settings
bool? isSiteCachingOn = null,
string activeTheme = null)
{
GroupFilterMapPage = groupFilterMapPage ?? new GroupFilterMapPage(); // Default behaviour: No filtering.
GroupFilterSettings = groupFilterSettings ?? new GroupFilterSettings(); // Default behaviour: No filtering.
GroupFilterMapPage = groupFilterMapPage ?? new GroupFilterMapPage(); // Default behavior: No filtering.
GroupFilterSettings = groupFilterSettings ?? new GroupFilterSettings(); // Default behavior: No filtering.
StartupSettings = startupSettings ?? new StartupSettings();
ActiveUri = GetActiveUri(activeUri);
PollingParameters = pollingParameters ?? PollingParameters.Default;
@ -64,7 +64,7 @@ namespace TINK.Model.Settings
ExpiresAfter = expiresAfter ?? DEFAULTEXPIRESAFTER;
ActiveLockService = activeLockService ?? LocksServicesContainerMutable.DefaultLocksservice;
ConnectTimeout = connectTimeout ?? new TimeSpan(0, 0, TimeOutProvider.DEFAULT_BLUETOOTHCONNECT_TIMEOUTSECONDS); // Try one sec. to connect.
ActiveGeolocationService = activeGeolocationService ?? DefaultLocationService.Name;
ActiveGeolocationService = activeGeolocationService ?? DefaultLocationService.FullName;
CenterMapToCurrentLocation = centerMapToCurrentLocation ?? GetCenterMapToCurrentLocation(activeUri);
MapSpan = mapSpan;
LogToExternalFolder = logToExternalFolder ?? false;
@ -78,7 +78,7 @@ namespace TINK.Model.Settings
/// <summary> Holds the filters loaded from settings. </summary>
public IGroupFilterSettings GroupFilterSettings { get; }
/// <summary> Holds the stettings determining app startup behavior. </summary>
/// <summary> Holds the settings determining app startup behavior. </summary>
public IStartupSettings StartupSettings { get; }
/// <summary> Holds the uri to connect to. </summary>
@ -102,7 +102,7 @@ namespace TINK.Model.Settings
/// <summary> Gets the geolocation service to use.</summary>
public string ActiveGeolocationService { get; }
/// <summary> True if map is centered to current positon, false if not to center map.</summary>
/// <summary> True if map is centered to current position, false if not to center map.</summary>
public bool CenterMapToCurrentLocation { get; }
/// <summary> Holds the map area to display. </summary>
@ -121,7 +121,7 @@ namespace TINK.Model.Settings
public static bool GetCenterMapToCurrentLocation(Uri activeUri)
{
// TINK does not require acess to current location. Deactivate center map to current location for this reason.
// TINK does not require access to current location. Deactivate center map to current location for this reason.
return !GetActiveUri(activeUri).Host.GetIsCopri();
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
namespace TINK.Model.State
{
@ -262,7 +262,7 @@ namespace TINK.Model.State
if (_RemainingTime.HasValue == false)
{
// Value was not yet querried.
// Do querry before returning object.
// Do query before returning object.
_StateInfo.GetIsStillReserved(out _RemainingTime);
}

View file

@ -1,8 +1,9 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using TINK.Model.Stations.StationNS;
namespace TINK.Model.Station
namespace TINK.Model.Stations
{
public class StationDictionary : IEnumerable<IStation>
{
@ -31,7 +32,7 @@ namespace TINK.Model.Station
}
/// <summary>
/// Deteermines whether a station by given key exists.
/// Determines whether a station by given key exists.
/// </summary>
/// <param name="key">Key to check.</param>
/// <returns>True if station exists.</returns>

View file

@ -1,7 +1,7 @@
using System.Collections.Generic;
using TINK.Model.Station.Operator;
using System.Collections.Generic;
using TINK.Model.Stations.StationNS.Operator;
namespace TINK.Model.Station
namespace TINK.Model.Stations.StationNS
{
public interface IStation
{

View file

@ -1,7 +1,7 @@
using System.Collections.Generic;
using TINK.Model.Station.Operator;
using System.Collections.Generic;
using TINK.Model.Stations.StationNS.Operator;
namespace TINK.Model.Station
namespace TINK.Model.Stations.StationNS
{
/// <summary> Holds object representing null station.</summary>
public class NullStation : IStation

View file

@ -1,6 +1,6 @@
using Xamarin.Forms;
using Xamarin.Forms;
namespace TINK.Model.Station.Operator
namespace TINK.Model.Stations.StationNS.Operator
{
/// <summary> Holds operator related data.</summary>
public class Data : IData

View file

@ -1,6 +1,6 @@
using Xamarin.Forms;
using Xamarin.Forms;
namespace TINK.Model.Station.Operator
namespace TINK.Model.Stations.StationNS.Operator
{
public interface IData
{

View file

@ -1,8 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using TINK.Model.Station.Operator;
using TINK.Model.Stations.StationNS.Operator;
namespace TINK.Model.Station
namespace TINK.Model.Stations.StationNS
{
/// <summary> Holds station info. </summary>
public class Station : IStation

View file

@ -13,7 +13,7 @@ using TINK.Model.Device;
using TINK.Model.Logging;
using TINK.Model.Services.CopriApi.ServerUris;
using TINK.Model.Settings;
using TINK.Model.Station;
using TINK.Model.Stations.StationNS;
using TINK.Model.User.Account;
using TINK.Services;
using TINK.Services.BluetoothLock;
@ -42,7 +42,7 @@ namespace TINK.Model
public static string MerchantId { get; private set; }
/// <summary>
/// Holds status about whants new page.
/// Holds status about whats new page.
/// </summary>
public WhatsNew WhatsNew { get; private set; }
@ -65,7 +65,7 @@ namespace TINK.Model
set => m_oFilterDictionaryMapPage = value ?? new GroupFilterMapPage();
}
/// <summary> Value indicating whether map is centerted to current position or not. </summary>
/// <summary> Value indicating whether map is centered to current position or not. </summary>
public bool CenterMapToCurrentLocation { get; set; }
/// <summary> Holds the map area to display when starting app for first time/ when center map to is off. </summary>
@ -123,7 +123,7 @@ namespace TINK.Model
/// <summary>
/// Update connector from filters when
/// - login state changes
/// - view is toggled (TINK to Kornrad and vice versa)
/// - view is toggled (TINK to Konrad and vice versa)
/// </summary>
public void UpdateConnector()
{
@ -133,7 +133,7 @@ namespace TINK.Model
m_oConnector.Connector);
}
/// <summary>Polling periode.</summary>
/// <summary>Polling period.</summary>
public PollingParameters Polling { get; set; }
public TimeSpan ExpiresAfter { get; set; }
@ -155,7 +155,7 @@ namespace TINK.Model
/// <param name="accountStore"></param>
/// <param name="passwordValidator"></param>
/// <param name="p_oConnectorFactory"></param>
/// <param name="geolocationService">Null in productive context. Service to querry geoloation for testing purposes. Parameter can be made optional.</param>
/// <param name="geolocationService">Null in productive context. Service to query geolocation for testing purposes. Parameter can be made optional.</param>
/// <param name="locksService">Null in productive context. Service to control locks/ get locks information for testing proposes. Parameter can be made optional.</param>
/// <param name="device">Object allowing platform specific operations.</param>
/// <param name="specialFolder"></param>
@ -176,7 +176,7 @@ namespace TINK.Model
string merchantId,
IBluetoothLE bluetoothService,
ILocationPermission locationPermissionsService,
IServicesContainer<IGeolocation> locationServicesContainer,
IServicesContainer<IGeolocationService> locationServicesContainer,
ILocksService locksService,
ISmartDevice device,
ISpecialFolder specialFolder,
@ -303,7 +303,7 @@ namespace TINK.Model
throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. Polling parameters must never be null.");
Polling = (lastVersion != null && lastVersion < new Version(3, 0, 358))
? PollingParameters.Default // Default polling periode was 10s up to 3.0.357. Is 60s for later versions.
? PollingParameters.Default // Default polling period was 10s up to 3.0.357. Is 60s for later versions.
: settings.PollingParameters;
AppVersion = currentVersion ?? new Version(3, 0, 122);
@ -342,7 +342,7 @@ namespace TINK.Model
/// <summary> Holds delegate to determine whether device is connected or not.</summary>
private readonly Func<bool> isConnectedFunc;
/// <summary> Gets whether device is connected to internet or not. </summary>
/// <summary> Gets whether device is connected to Internet or not. </summary>
public bool GetIsConnected() => isConnectedFunc();
/// <summary> Holds the folder where settings files are stored. </summary>
@ -365,8 +365,8 @@ namespace TINK.Model
/// <summary> Name of the station which is selected. </summary>
public IStation SelectedStation { get; set; } = new NullStation();
/// <summary> Holds the stations availalbe. </summary>
public IEnumerable<IStation> Stations { get; set; } = new List<Station.Station>();
/// <summary> Holds the stations centered. </summary>
public IEnumerable<IStation> Stations { get; set; } = new List<Station>();
public IResourceUrls ResourceUrls { get; set; } = new ResourceUrls();
@ -406,7 +406,7 @@ namespace TINK.Model
public LocksServicesContainerMutable LocksServices { get; set; }
/// <summary> Holds available app themes.</summary>
public IServicesContainer<IGeolocation> GeolocationServices { get; }
public IServicesContainer<IGeolocationService> GeolocationServices { get; }
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or Lastenrad Bayern.</summary>
public AppFlavor Flavor { get; private set; }

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,15 +10,15 @@ namespace TINK.Model.User.Account
{
None = 0, // No extra permissions.
PickCopriServer = 2, // Allows user to switch COPRI server.
ManageCopriCacheExpiration = 4, // Allows to manage the livetime of COPRI cache entries.
ManagePolling = 8, // Turn polling off or on and set pollig frequency.
PickLockServiceImplementation = 16, // Allows to pick the implementation which controls bluetooth lock mangement.
ManageCopriCacheExpiration = 4, // Allows to manage the live time of COPRI cache entries.
ManagePolling = 8, // Turn polling off or on and set polling frequency.
PickLockServiceImplementation = 16, // Allows to pick the implementation which controls bluetooth lock management.
PickLocationServiceImplementation = 32, // Allows to pick the implementation which gets location information.
PickLoggingLevel = 64, // Allows to select the logging level.
ShowDiagnostics = 128, // Turns on display of diagnostics.
SwitchNoSiteCaching = 1024, // Allows to turn off/ on caching of sites displayed in app hosted by COPRI
ReportLevel = 2048, // Allows extent to show error messages.
SwitchTheme = 4096, // Allows user to switch theme (sharee.bike, Meinkonrad, Lastenrad Bayern)
SwitchTheme = 4096, // Allows user to switch theme (sharee.bike, Mein konrad, LastenRad Bayern)
All = PickCopriServer +
ManageCopriCacheExpiration +
ManagePolling +
@ -57,7 +57,7 @@ namespace TINK.Model.User.Account
/// <param name="mail">Mail address of the account holder.</param>
/// <param name="password">Password.</param>
/// <param name="sessionCookie">Session cookie from copri.</param>
/// <param name="bikeGroup">Group holdig info about Group (TINK, Konrad, ...)</param>
/// <param name="bikeGroup">Group holding info about Group (TINK, Konrad, ...)</param>
/// <param name="p_iDebugLevel">Flag which controls display of debug settings.</param>
public Account(
string mail,
@ -87,7 +87,7 @@ namespace TINK.Model.User.Account
/// <summary>Password of to authenticate.</summary>
public string Pwd { get; }
/// <summary>True if user acknowleged agbs.</summary>
/// <summary>True if user acknowledged AGBs.</summary>
public bool IsAgbAcknowledged { get; }
/// <summary>Session cookie used to sign in to copri.</summary>

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