mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-21 21:46:27 +02:00
Version 3.0.290
This commit is contained in:
parent
af3c20ea1c
commit
ad3cdbcadf
231 changed files with 14555 additions and 7798 deletions
|
@ -111,6 +111,16 @@ namespace TINK.Model.Connector
|
|||
/// <param name="bike">Bike to update locking state for.</param>
|
||||
/// <param name="location">Location where lock was opened/ changed.</param>
|
||||
/// <returns>Response on updating locking state.</returns>
|
||||
public async Task StartReturningBike(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike)
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected request to notify about start of returning bike. No user logged in.");
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary> Notifies COPRI about start of returning sequence. </summary>
|
||||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
/// <returns>Response on notification about start of returning sequence.</returns>
|
||||
public async Task UpdateLockingStateAsync(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto location)
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected request to update locking state detected. No user logged in.");
|
||||
|
|
|
@ -159,15 +159,42 @@ namespace TINK.Model.Connector
|
|||
Bikes.Bike.BC.NotifyPropertyChangedLevel.None);
|
||||
}
|
||||
|
||||
/// <summary> Updates COPRI lock state for a booked bike. </summary>
|
||||
/// <param name="bike">Bike to update locking state for.</param>
|
||||
/// <returns>Response on updating locking state.</returns>
|
||||
public async Task UpdateLockingStateAsync(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto location)
|
||||
/// <summary> Notifies COPRI about start of returning sequence. </summary>
|
||||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
/// <returns>Response on notification about start of returning sequence.</returns>
|
||||
public async Task StartReturningBike(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike)
|
||||
{
|
||||
if (bike == null)
|
||||
{
|
||||
throw new ArgumentNullException("Can not book bike. No bike object available.");
|
||||
throw new ArgumentNullException("Can not notify about start returning bike. No bike object available.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
(await CopriServer.StartReturningBike(
|
||||
bike.Id,
|
||||
bike.OperatorUri)).GetIsResponseOk("Start returning bike");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Exception was not expected or too many subsequent excepitons detected.
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Updates COPRI lock state for a booked bike. </summary>
|
||||
/// <param name="bike">Bike to update locking state for.</param>
|
||||
/// <param name="location">Location of the bike.</param>
|
||||
/// <returns>Response on updating locking state.</returns>
|
||||
public async Task UpdateLockingStateAsync(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location)
|
||||
{
|
||||
if (bike == null)
|
||||
{
|
||||
throw new ArgumentNullException("Can not update locking state of bike. No bike object available.");
|
||||
}
|
||||
|
||||
if (bike.State.Value != State.InUseStateEnum.Booked)
|
||||
|
|
|
@ -25,19 +25,25 @@ namespace TINK.Model.Connector
|
|||
Task DoLogout();
|
||||
|
||||
/// <summary> Request to reserve a bike.</summary>
|
||||
/// <param name="p_oBike">Bike to book.</param>
|
||||
Task DoReserve(Bikes.Bike.BC.IBikeInfoMutable p_oBike);
|
||||
/// <param name="bike">Bike to book.</param>
|
||||
Task DoReserve(Bikes.Bike.BC.IBikeInfoMutable bike);
|
||||
|
||||
/// <summary> Request to cancel a reservation.</summary>
|
||||
/// <param name="p_oBike">Bike to book.</param>
|
||||
Task DoCancelReservation(Bikes.Bike.BC.IBikeInfoMutable p_oBike);
|
||||
/// <param name="bike">Bike to book.</param>
|
||||
Task DoCancelReservation(Bikes.Bike.BC.IBikeInfoMutable bike);
|
||||
|
||||
/// <summary> Get authentication keys to connect to lock.</summary>
|
||||
/// <param name="bike">Bike to book.</param>
|
||||
Task CalculateAuthKeys(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike);
|
||||
|
||||
/// <summary> Notifies COPRI about start of returning sequence. </summary>
|
||||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
/// <returns>Response on notification about start of returning sequence.</returns>
|
||||
Task StartReturningBike(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike);
|
||||
|
||||
/// <summary> Updates COPRI lock state for a booked bike. </summary>
|
||||
/// <param name="bikeId">Id of the bike to update locking state for.</param>
|
||||
/// <param name="bike">Bike to update locking state for.</param>
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <returns>Response on updating locking state.</returns>
|
||||
Task UpdateLockingStateAsync(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto location = null);
|
||||
|
@ -90,8 +96,8 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
|
||||
/// <summary>Defines delegate to be raised whenever login state changes.</summary>
|
||||
/// <param name="p_oEventArgs">Holds session cookie and mail address if user logged in successfully.</param>
|
||||
public delegate void LoginStateChangedEventHandler(object p_oSender, LoginStateChangedEventArgs p_oEventArgs);
|
||||
/// <param name="eventArgs">Holds session cookie and mail address if user logged in successfully.</param>
|
||||
public delegate void LoginStateChangedEventHandler(object sender, LoginStateChangedEventArgs eventArgs);
|
||||
|
||||
#if !USCSHARP9
|
||||
/// <summary>
|
||||
|
@ -123,10 +129,10 @@ namespace TINK.Model.Connector
|
|||
public LoginStateChangedEventArgs() : this(string.Empty, string.Empty)
|
||||
{ }
|
||||
|
||||
public LoginStateChangedEventArgs(string p_strSessionCookie, string p_strMail)
|
||||
public LoginStateChangedEventArgs(string sessionCookie, string mail)
|
||||
{
|
||||
SessionCookie = p_strSessionCookie;
|
||||
Mail = p_strMail;
|
||||
SessionCookie = sessionCookie;
|
||||
Mail = mail;
|
||||
}
|
||||
|
||||
public string SessionCookie { get; }
|
||||
|
|
|
@ -4,10 +4,9 @@ using Serilog.Events;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Services.Geolocation;
|
||||
using TINK.Settings;
|
||||
using TINK.ViewModel.Map;
|
||||
using TINK.ViewModel.Settings;
|
||||
|
@ -155,14 +154,14 @@ namespace TINK.Model.Settings
|
|||
|
||||
/// <summary> Sets the version of the app. </summary>
|
||||
/// <param name="settingsJSON">Dictionary holding parameters from JSON.</param>
|
||||
public static Dictionary<string, string> SetAppVersion(this IDictionary<string, string> p_oTargetDictionary, Version p_strAppVersion)
|
||||
public static Dictionary<string, string> SetAppVersion(this IDictionary<string, string> targetDictionary, Version appVersion)
|
||||
{
|
||||
if (p_oTargetDictionary == null)
|
||||
if (targetDictionary == null)
|
||||
throw new Exception("Writing copri host uri to dictionary failed. Dictionary must not be null.");
|
||||
|
||||
return p_oTargetDictionary.Union(new Dictionary<string, string>
|
||||
return targetDictionary.Union(new Dictionary<string, string>
|
||||
{
|
||||
{APPVERIONKEY , JsonConvert.SerializeObject(p_strAppVersion, new VersionConverter()) },
|
||||
{APPVERIONKEY , JsonConvert.SerializeObject(appVersion, new VersionConverter()) },
|
||||
}).ToDictionary(key => key.Key, value => value.Value);
|
||||
}
|
||||
|
||||
|
@ -172,16 +171,16 @@ namespace TINK.Model.Settings
|
|||
public static Version GetAppVersion(this IDictionary<string, string> settingsJSON)
|
||||
{
|
||||
// Get the version of the app which wrote the settings file.
|
||||
if (!settingsJSON.TryGetValue(APPVERIONKEY, out string l_oAppVersion)
|
||||
|| string.IsNullOrEmpty(l_oAppVersion))
|
||||
if (!settingsJSON.TryGetValue(APPVERIONKEY, out string appVersion)
|
||||
|| string.IsNullOrEmpty(appVersion))
|
||||
{
|
||||
// File holds no entry.
|
||||
return null;
|
||||
}
|
||||
|
||||
return l_oAppVersion.TrimStart().StartsWith("\"")
|
||||
? JsonConvert.DeserializeObject<Version>(l_oAppVersion, new VersionConverter())
|
||||
: Version.Parse(l_oAppVersion); // Format used up to version 3.0.0.115
|
||||
return appVersion.TrimStart().StartsWith("\"")
|
||||
? JsonConvert.DeserializeObject<Version>(appVersion, new VersionConverter())
|
||||
: Version.Parse(appVersion); // Format used up to version 3.0.0.115
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,21 +219,21 @@ namespace TINK.Model.Settings
|
|||
}
|
||||
|
||||
/// <summary> Saves object to file. </summary>
|
||||
/// <param name="p_SettingsList">Settings to save.</param>
|
||||
public static void Serialize(string p_strSettingsFileFolder, IDictionary<string, string> p_SettingsList)
|
||||
/// <param name="settingsList">Settings to save.</param>
|
||||
public static void Serialize(string settingsFileFolder, IDictionary<string, string> settingsList)
|
||||
{
|
||||
// Save settings to file.
|
||||
var l_oText = JsonConvert.SerializeObject(p_SettingsList, Formatting.Indented);
|
||||
var l_oFolder = p_strSettingsFileFolder;
|
||||
var l_oText = JsonConvert.SerializeObject(settingsList, Formatting.Indented);
|
||||
var l_oFolder = settingsFileFolder;
|
||||
System.IO.File.WriteAllText($"{l_oFolder}{System.IO.Path.DirectorySeparatorChar}{SETTINGSFILETITLE}", l_oText);
|
||||
}
|
||||
|
||||
/// <summary> Gets TINK app settings form xml- file. </summary>
|
||||
/// <param name="p_strSettingsDirectory">Directory to read settings from.</param>
|
||||
/// <param name="settingsDirectory">Directory to read settings from.</param>
|
||||
/// <returns>Dictionary of settings.</returns>
|
||||
public static Dictionary<string, string> Deserialize(string p_strSettingsDirectory)
|
||||
public static Dictionary<string, string> Deserialize(string settingsDirectory)
|
||||
{
|
||||
var l_oFileName = $"{p_strSettingsDirectory}{System.IO.Path.DirectorySeparatorChar}{SETTINGSFILETITLE}";
|
||||
var l_oFileName = $"{settingsDirectory}{System.IO.Path.DirectorySeparatorChar}{SETTINGSFILETITLE}";
|
||||
|
||||
if (!System.IO.File.Exists(l_oFileName))
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Serilog.Events;
|
||||
using System;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Services.Geolocation;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.CopriApi.ServerUris;
|
||||
using TINK.Settings;
|
||||
|
@ -18,7 +18,8 @@ namespace TINK.Model.Settings
|
|||
public const bool DEFAULTREPOTLEVEL = false;
|
||||
|
||||
/// <summary> Gets the type of the default geolocation service. </summary>
|
||||
public static Type DefaultLocationService => typeof(GeolocationService);
|
||||
/// <remarks> Swtiched 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.
|
||||
private TimeSpan DEFAULTEXPIRESAFTER = TimeSpan.FromSeconds(1);
|
||||
|
|
|
@ -13,9 +13,8 @@ using Serilog;
|
|||
using Plugin.Connectivity;
|
||||
using System.Threading;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Services.Geolocation;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using Plugin.Permissions.Abstractions;
|
||||
using TINK.Services.BluetoothLock.Crypto;
|
||||
using TINK.ViewModel.Map;
|
||||
using TINK.ViewModel.Settings;
|
||||
|
@ -23,12 +22,16 @@ using TINK.Services;
|
|||
using TINK.Services.BluetoothLock.BLE;
|
||||
using Xamarin.Forms;
|
||||
using TINK.Model.Station;
|
||||
using TINK.Services.Permissions;
|
||||
using Plugin.BLE.Abstractions.Contracts;
|
||||
|
||||
namespace TINK.Model
|
||||
{
|
||||
[DataContract]
|
||||
public class TinkApp : ITinkApp
|
||||
{
|
||||
private const string PLATFORMANDROID = "ANDROID";
|
||||
|
||||
/// <summary> Delegate used by login view to commit user name and password. </summary>
|
||||
/// <param name="p_strMailAddress">Mail address used as id login.</param>
|
||||
/// <param name="p_strPassword">Password for login.</param>
|
||||
|
@ -159,16 +162,17 @@ namespace TINK.Model
|
|||
public TinkApp(
|
||||
Settings.Settings settings,
|
||||
IStore accountStore,
|
||||
Func<bool> isConnectedFunc,
|
||||
Func<bool, Uri, string /* session cookie*/, string /* mail address*/, TimeSpan, IConnector> connectorFactory,
|
||||
string merchantId,
|
||||
IServicesContainer<IGeolocation> geolocationServicesContainer,
|
||||
IBluetoothLE bluetoothService,
|
||||
ILocationPermission locationPermissionsService,
|
||||
IServicesContainer<IGeolocation> locationServicesContainer,
|
||||
ILocksService locksService,
|
||||
ISmartDevice device,
|
||||
ISpecialFolder specialFolder,
|
||||
ICipher cipher,
|
||||
IPermissions permissions = null,
|
||||
object arendiCentral = null,
|
||||
Func<bool> isConnectedFunc = null,
|
||||
Action<SendOrPostCallback, object> postAction = null,
|
||||
Version currentVersion = null,
|
||||
Version lastVersion = null,
|
||||
|
@ -185,11 +189,21 @@ namespace TINK.Model
|
|||
|
||||
Cipher = cipher ?? new Cipher();
|
||||
|
||||
bool GetIsAndroid(string platformText) => platformText.ToUpper().Contains(PLATFORMANDROID);
|
||||
|
||||
var locksServices = locksService != null
|
||||
? new HashSet<ILocksService> { locksService }
|
||||
: new HashSet<ILocksService> {
|
||||
new LockItByScanServiceEventBased(Cipher),
|
||||
new LockItByScanServicePolling(Cipher),
|
||||
new LockItByScanServiceEventBased(
|
||||
Cipher,
|
||||
bluetoothService,
|
||||
async () => GetIsAndroid(device.PlatformText) && await locationPermissionsService.CheckStatusAsync() != Status.Granted,
|
||||
() => GetIsAndroid(device.PlatformText) && !locationServicesContainer.Active.IsGeolcationEnabled),
|
||||
new LockItByScanServicePolling(
|
||||
Cipher,
|
||||
bluetoothService,
|
||||
async () => GetIsAndroid(device.PlatformText) && await locationPermissionsService.CheckStatusAsync() != Status.Granted,
|
||||
() => GetIsAndroid(device.PlatformText) && !locationServicesContainer.Active.IsGeolcationEnabled),
|
||||
new LockItByGuidService(Cipher),
|
||||
#if BLUETOOTHLE // Requires LockItBluetoothle library.
|
||||
new Bluetoothle.LockItByGuidService(Cipher),
|
||||
|
@ -216,7 +230,7 @@ namespace TINK.Model
|
|||
},
|
||||
settings.ActiveTheme);
|
||||
|
||||
GeolocationServices = geolocationServicesContainer
|
||||
GeolocationServices = locationServicesContainer
|
||||
?? throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. No geolocation services container object available.");
|
||||
|
||||
FilterGroupSetting = settings.GroupFilterSettings;
|
||||
|
|
|
@ -477,11 +477,43 @@ namespace TINK.Model
|
|||
},
|
||||
{
|
||||
new Version(3, 0, 276),
|
||||
AppResources.ChangeLog3_0_276
|
||||
AppResources.ChangeLog3_0_276
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 277),
|
||||
AppResources.ChangeLog3_0_277
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 279),
|
||||
AppResources.ChangeLog3_0_278 // Addition spelling corrected and missing translation added.
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 280),
|
||||
AppResources.ChangeLog3_0_280
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 281),
|
||||
AppResources.ChangeLog3_0_280
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 283),
|
||||
AppResources.ChangeLog3_0_282
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 284),
|
||||
AppResources.ChangeLog3_0_284
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 285),
|
||||
AppResources.ChangeLog3_0_285
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 289),
|
||||
AppResources.ChangeLog3_0_289
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 290),
|
||||
AppResources.ChangeLog3_0_290
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue