diff --git a/TINKLib/ViewModel/FindBike/FindBikePageViewModel.cs b/TINKLib/ViewModel/FindBike/FindBikePageViewModel.cs
index 908c372..b7f11e6 100644
--- a/TINKLib/ViewModel/FindBike/FindBikePageViewModel.cs
+++ b/TINKLib/ViewModel/FindBike/FindBikePageViewModel.cs
@@ -29,6 +29,13 @@ namespace TINK.ViewModel.FindBike
{
public class FindBikePageViewModel : BikesViewModel, INotifyCollectionChanged, INotifyPropertyChanged
{
+
+ /// Text entered by user to specify a bike.
+ public string BikeIdUserInput { get; set; }
+
+ /// Holds all bikes available.
+ public BikeCollection Bikes { get; set; }
+
///
/// Constructs bike collection view model in case information about occupied bikes is available.
///
@@ -66,23 +73,174 @@ namespace TINK.ViewModel.FindBike
///
public async Task OnAppearing()
{
- // Get my bikes from COPRI
- Log.ForContext().Information("User request to show page MyBikes/ page re-appearing");
+ Log.ForContext().Information("User request to show page FindBike- page re-appearing");
ActionText = AppResources.ActivityTextMyBikesLoadingBikes;
var bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
Exception = bikes.Exception; // Update communication error from query for bikes occupied.
-
- BikeIds = bikes.Response.Select(x => x.Id);
+ Bikes = bikes.Response;
ActionText = "";
IsIdle = true;
}
+ /// Command object to bind select bike button to view model.
+ public System.Windows.Input.ICommand OnSelectBikeRequest => new Xamarin.Forms.Command(async () => await SelectBike());
- public IEnumerable BikeIds { get; set; }
+ /// Select a bike by ID
+ public async Task SelectBike()
+ {
+ var selectedBike = Bikes.FirstOrDefault(x => x.Id == BikeIdUserInput);
+ if (selectedBike == null)
+ {
+ await ViewService.DisplayAlert("Fehler bei Radauswahl!", $"Kein Rad mit Id {BikeIdUserInput} gefunden.", "OK");
+ return;
+ }
+
+ var bikeCollection = new BikeCollection(new Dictionary { { selectedBike.Id, selectedBike } });
+
+ var lockIdList = bikeCollection
+ .GetLockIt()
+ .Cast()
+ .Select(x => x.LockInfo)
+ .ToList();
+
+ if (LockService is ILocksServiceFake serviceFake)
+ {
+ serviceFake.UpdateSimulation(bikeCollection);
+ }
+
+ // Check bluetooth and location permission and states
+ ActionText = AppResources.ActivityTextCheckBluetoothState;
+
+ if (bikeCollection.FirstOrDefault(x => x is BikeInfo btBike) != null
+ && RuntimePlatform == Device.Android)
+ {
+ // Check location permission
+ var status = await PermissionsService.CheckPermissionStatusAsync();
+ if (status != PermissionStatus.Granted)
+ {
+ var permissionResult = await PermissionsService.RequestPermissionAsync();
+
+ if (permissionResult != PermissionStatus.Granted)
+ {
+ var dialogResult = await ViewService.DisplayAlert(
+ AppResources.MessageTitleHint,
+ AppResources.MessageBikesManagementLocationPermissionOpenDialog,
+ AppResources.MessageAnswerYes,
+ AppResources.MessageAnswerNo);
+
+ if (!dialogResult)
+ {
+ // User decided not to give access to locations permissions.
+ BikeCollection.Update(bikeCollection);
+
+ //await OnAppearing(() => UpdateTask());
+
+ ActionText = "";
+ IsIdle = true;
+ return;
+ }
+
+ // Open permissions dialog.
+ PermissionsService.OpenAppSettings();
+ }
+ }
+
+ // Location state
+ if (Geolocation.IsGeolcationEnabled == false)
+ {
+ await ViewService.DisplayAlert(
+ AppResources.MessageTitleHint,
+ AppResources.MessageBikesManagementLocationActivation,
+ AppResources.MessageAnswerOk);
+
+ BikeCollection.Update(bikeCollection);
+
+ await OnAppearing(() => UpdateTask());
+
+ ActionText = "";
+ IsIdle = true;
+ return;
+ }
+
+ // Bluetooth state
+ if (await BluetoothService.GetBluetoothState() != BluetoothState.On)
+ {
+ await ViewService.DisplayAlert(
+ AppResources.MessageTitleHint,
+ AppResources.MessageBikesManagementBluetoothActivation,
+ AppResources.MessageAnswerOk);
+
+ BikeCollection.Update(bikeCollection);
+
+ await OnAppearing(() => UpdateTask());
+
+ ActionText = "";
+ IsIdle = true;
+ return;
+ }
+ }
+
+ // Connect to bluetooth devices.
+ ActionText = AppResources.ActivityTextSearchBikes;
+ IEnumerable locksInfoTdo;
+ try
+ {
+ locksInfoTdo = await LockService.GetLocksStateAsync(
+ lockIdList.Select(x => x.ToLockInfoTdo()).ToList(),
+ LockService.TimeOut.MultiConnect);
+ }
+ catch (Exception exception)
+ {
+ Log.ForContext().Error("Getting bluetooth state failed. {Exception}", exception);
+ locksInfoTdo = new List();
+ }
+
+ var locksInfo = lockIdList.UpdateById(locksInfoTdo);
+
+ BikeCollection.Update(bikeCollection.UpdateLockInfo(locksInfo));
+
+ await OnAppearing(() => UpdateTask());
+
+ ActionText = "";
+ IsIdle = true;
+
+ }
+
+ /// Create task which updates my bike view model.
+ private void UpdateTask()
+ {
+ // Start task which periodically updates pins.
+ PostAction(
+ unused =>
+ {
+ ActionText = AppResources.ActivityTextUpdating;
+ IsConnected = IsConnectedDelegate();
+ },
+ null);
+
+ var result = ConnectorFactory(IsConnected).Query.GetBikesOccupiedAsync().Result;
+
+ var bikes = result.Response;
+
+ var exception = result.Exception;
+ if (exception != null)
+ {
+ Log.ForContext().Error("Getting bikes occupied in polling context failed with exception {Exception}.", exception);
+ }
+
+ PostAction(
+ unused =>
+ {
+ BikeCollection.Update(bikes); // Updating collection leads to update of GUI.
+ Exception = result.Exception;
+ ActionText = string.Empty;
+ },
+ null);
+ }
}
}