mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-04-21 12:36:28 +02:00
Version 3.0.381
This commit is contained in:
parent
f963c0a219
commit
3a363acf3a
1525 changed files with 60589 additions and 125098 deletions
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public abstract class Base : BC.RequestHandler.Base<Model.Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs the request handler base.
|
||||
/// </summary>
|
||||
/// <param name="selectedBike">Bike which is reserved or for which reservation is canceled.</param>
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public Base(
|
||||
Model.Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable selectedBike,
|
||||
string buttonText,
|
||||
bool isCopriButtonVisible,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(selectedBike, buttonText, isCopriButtonVisible, isConnectedDelegate, connectorFactory, viewUpdateManager, smartDevice, viewService, bikesViewModel, activeUser)
|
||||
{
|
||||
GeolocationService = geolocation
|
||||
?? throw new ArgumentException($"Can not construct {GetType().Name}-object. Parameter {nameof(geolocation)} must not be null.");
|
||||
|
||||
LockService = lockService
|
||||
?? throw new ArgumentException($"Can not construct {GetType().Name}-object. Parameter {nameof(lockService)} must not be null.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service to query geolocation information.
|
||||
/// </summary>
|
||||
protected IGeolocationService GeolocationService { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Service to control locks.
|
||||
/// </summary>
|
||||
protected ILocksService LockService { get; }
|
||||
|
||||
public string LockitButtonText { get; protected set; }
|
||||
|
||||
public bool IsLockitButtonVisible { get; protected set; }
|
||||
|
||||
public string ErrorText => string.Empty;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using EndRentalCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.EndRentalCommand;
|
||||
using OpenCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.OpenCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class BookedClosed : Base, IRequestHandler, EndRentalCommand.IEndRentalCommandListener, OpenCommand.IOpenCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public BookedClosed(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionEndRental, // End Rental
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionOpenLock; // Open Lock
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_openLockActionViewModel = new OpenLockActionViewModel<BookedClosed>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_endRentalActionViewModel = new EndRentalActionViewModel<BookedClosed>(
|
||||
selectedBike,
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for end rental action.
|
||||
/// </summary>
|
||||
private readonly EndRentalActionViewModel<BookedClosed> _endRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the get lock location progress.
|
||||
/// </summary>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(EndRentalCommand.Step step) => _endRentalActionViewModel.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the get lock location state.
|
||||
/// </summary>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(EndRentalCommand.State state, string details) => await _endRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
/// <summary> End Rental. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _endRentalActionViewModel.EndRentalAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly OpenLockActionViewModel<BookedClosed> _openLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the open lock progress.
|
||||
/// </summary>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(OpenCommand.Step step) => _openLockActionViewModel.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the open lock state.
|
||||
/// </summary>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(OpenCommand.State state, string details) => await _openLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary> Open lock. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _openLockActionViewModel.OpenLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using ConnectCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.ConnectAndGetStateCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class BookedDisconnected : Base, IRequestHandler, ConnectCommand.IConnectAndGetStateCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public BookedDisconnected(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) :
|
||||
base(
|
||||
selectedBike,
|
||||
AppResources.ActionSearchLock, // Connect Lock
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = GetType().Name;
|
||||
IsLockitButtonVisible = false;
|
||||
|
||||
_connectLockActionViewModel = new ConnectLockActionViewModel<BookedDisconnected>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for connecting to lock action.
|
||||
/// </summary>
|
||||
private readonly ConnectLockActionViewModel<BookedDisconnected> _connectLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the connect to lock progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(ConnectCommand.Step step) => _connectLockActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the connect to lock state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(ConnectCommand.State state, string details) => await _connectLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption2() => await UnsupportedRequest();
|
||||
|
||||
/// <summary> Scan for lock.</summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _connectLockActionViewModel.ConnectLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary> Request is not supported, button should be disabled. </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> UnsupportedRequest()
|
||||
{
|
||||
Log.ForContext<BookedDisconnected>().Error("Click of unsupported button click detected.");
|
||||
return await Task.FromResult<IRequestHandler>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using CloseCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
using ShareeBike.Services.BluetoothLock.Exception;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class BookedOpen : Base, IRequestHandler, CloseCommand.ICloseCommandListener
|
||||
{
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public BookedOpen(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionCloseLock, // Close Lock
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = activeUser.DebugLevel.HasFlag(Model.User.Account.Permissions.ManageAlarmAndSounds) ? AppResources.ActionLockSettings : GetType().Name;
|
||||
IsLockitButtonVisible = activeUser.DebugLevel.HasFlag(Model.User.Account.Permissions.ManageAlarmAndSounds);
|
||||
|
||||
_closeLockActionViewModel = new CloseLockActionViewModel<BookedOpen>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly CloseLockActionViewModel<BookedOpen> _closeLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CloseCommand.Step step) => _closeLockActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CloseCommand.State state, string details) => await _closeLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary> Close lock (and return bike).</summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _closeLockActionViewModel.CloseLockAsync();
|
||||
if(_closeLockActionViewModel.IsEndRentalRequested == false)
|
||||
{
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
var _endRentalActionViewModel = new EndRentalActionViewModel<BookedClosed>(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
ViewUpdateManager,
|
||||
ViewService,
|
||||
BikesViewModel);
|
||||
|
||||
await _endRentalActionViewModel.EndRentalAsync();
|
||||
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
if (ActiveUser.DebugLevel.HasFlag(Model.User.Account.Permissions.ManageAlarmAndSounds))
|
||||
{
|
||||
await ManageLockSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary> Manage sound/ alarm settings. </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> ManageLockSettings()
|
||||
{
|
||||
// Stop polling before requesting bike.
|
||||
BikesViewModel.ActionText = AppResources.ActivityTextOneMomentPlease;
|
||||
await ViewUpdateManager().StopAsync();
|
||||
|
||||
// Go to lock settings
|
||||
Log.ForContext<ReservedOpen>().Information("User selected bike {bikeId} in order to manage sound/ alarm settings.", SelectedBike.Id);
|
||||
|
||||
// Alarm settings
|
||||
var resultAlarm = await ViewService.DisplayAlert(
|
||||
"Alarm einstellen",
|
||||
"Alarm auf Einstellung 'niedrige Sensitivität' setzen oder Alarm ausschalten?",
|
||||
"Auf niedrige Sensitivität",
|
||||
"Alarm aus");
|
||||
|
||||
try
|
||||
{
|
||||
if (resultAlarm == true)
|
||||
{
|
||||
// Lower alarm sensitivity.
|
||||
BikesViewModel.ActionText = "Setzen Alarm-Einstellungen...";
|
||||
await LockService[SelectedBike.LockInfo.Id].SetAlarmSettingsAsync(AlarmSettings.SmallSensivitySilent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Switch off alarm.
|
||||
BikesViewModel.ActionText = "Alarm ausschalten...";
|
||||
await LockService[SelectedBike.LockInfo.Id].SetIsAlarmOffAsync(true);
|
||||
}
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Debug("Can not set alarm settings. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Setzen der Alarm-Einstellungen!",
|
||||
"Alarm kann erst eingestellt werden, wenn Rad in der Nähe ist.",
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
return this;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Error("Can not set alarm settings. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Setzen der Alarms-Einstellungen!",
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Sound settings
|
||||
var resultSound = await ViewService.DisplayAlert(
|
||||
"Sounds einstellen",
|
||||
"Sounds auf Einstellung 'Warnung' setzen oder alle Sounds ausschalten?",
|
||||
"Auf Warnung",
|
||||
"Alles aus");
|
||||
|
||||
try
|
||||
{
|
||||
if (resultSound == true)
|
||||
{
|
||||
BikesViewModel.ActionText = "Sounds einstellen auf 'Warnung'...";
|
||||
await LockService[SelectedBike.LockInfo.Id].SetSoundAsync(SoundSettings.Warn);
|
||||
}
|
||||
else
|
||||
{
|
||||
BikesViewModel.ActionText = "Alle Sounds ausschalten...";
|
||||
await LockService[SelectedBike.LockInfo.Id].SetSoundAsync(SoundSettings.AllOff);
|
||||
}
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Debug("Can not set sounds. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Einstellen der Sounds!",
|
||||
"Sounds können erst eingestellt werden, wenn Rad in der Nähe ist.",
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
return this;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Error("Can not set sounds. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Einstellen der Sounds!",
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
return Create(SelectedBike, IsConnectedDelegate, ConnectorFactory, GeolocationService, LockService, ViewUpdateManager, SmartDevice, ViewService, BikesViewModel, ActiveUser);
|
||||
}
|
||||
|
||||
BikesViewModel.ActionText = AppResources.ActivityTextStartingUpdater;
|
||||
await ViewUpdateManager().StartAsync(); // Restart polling again.
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
BikesViewModel.IsIdle = true; // Unlock GUI
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary> Request is not supported, button should be disabled. </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> UnsupportedRequest()
|
||||
{
|
||||
Log.ForContext<DisposableDisconnected>().Error("Click of unsupported button click detected.");
|
||||
return await Task.FromResult<IRequestHandler>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using CloseCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand;
|
||||
using OpenCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.OpenCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class BookedUnknown : Base, IRequestHandler, CloseCommand.ICloseCommandListener, OpenCommand.IOpenCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...).</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public BookedUnknown(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionOpenLock, // Open Lock
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionCloseLock; // Close Lock
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_openLockActionViewModel = new OpenLockActionViewModel<BookedUnknown>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_closeLockActionViewModel = new CloseLockActionViewModel<BookedUnknown>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly OpenLockActionViewModel<BookedUnknown> _openLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the open lock progress.
|
||||
/// </summary>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(OpenCommand.Step step) => _openLockActionViewModel.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the open lock state.
|
||||
/// </summary>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(OpenCommand.State state, string details) => await _openLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
/// <summary> Open bike and update COPRI lock state. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _openLockActionViewModel.OpenLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly CloseLockActionViewModel<BookedUnknown> _closeLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CloseCommand.Step step) => _closeLockActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CloseCommand.State state, string details) => await _closeLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary> Close lock in order to pause ride and update COPRI lock state.</summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _closeLockActionViewModel.CloseLockAsync();
|
||||
if (_closeLockActionViewModel.IsEndRentalRequested == false)
|
||||
{
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
var _endRentalActionViewModel = new EndRentalActionViewModel<BookedClosed>(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
ViewUpdateManager,
|
||||
ViewService,
|
||||
BikesViewModel);
|
||||
|
||||
await _endRentalActionViewModel.EndRentalAsync();
|
||||
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using StartReservationCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartReservationCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class DisposableDisconnected : Base, IRequestHandler, StartReservationCommand.IStartReservationCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...).</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public DisposableDisconnected(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionRequestBike, // Reserve / Rent Bike
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = GetType().Name;
|
||||
IsLockitButtonVisible = false;
|
||||
|
||||
_startReservationOrRentalActionViewModel = new StartReservationOrRentalActionViewModel<DisposableDisconnected>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly StartReservationOrRentalActionViewModel<DisposableDisconnected> _startReservationOrRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the reserving a bike progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(StartReservationCommand.Step step) => _startReservationOrRentalActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the reserving a bike state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(StartReservationCommand.State state, string details) => await _startReservationOrRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary>Reserve bike, connect to lock, open lock and rent bike.</summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _startReservationOrRentalActionViewModel.StartReservationOrRentalAsync();
|
||||
if (_startReservationOrRentalActionViewModel.ContinueWithOpenLock == false)
|
||||
{
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
var _openLockActionViewModel = new OpenLockActionViewModel<BookedClosed>(
|
||||
SelectedBike,
|
||||
ViewUpdateManager,
|
||||
ViewService,
|
||||
BikesViewModel);
|
||||
|
||||
await _openLockActionViewModel.OpenLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption2() => await UnsupportedRequest();
|
||||
|
||||
/// <summary> Request is not supported, button should be disabled. </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> UnsupportedRequest()
|
||||
{
|
||||
Log.ForContext<DisposableDisconnected>().Error("Click of unsupported button click detected.");
|
||||
return await Task.FromResult<IRequestHandler>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using StartReservationCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartReservationCommand;
|
||||
using CloseCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
/// <summary> Bike is disposable, lock is open and connected to app. </summary>
|
||||
/// <remarks>
|
||||
/// This state can not be occur because
|
||||
/// - app does not allow to return bike/ cancel reservation when lock is not closed
|
||||
/// - as long as app is connected to lock
|
||||
/// - lock can not be opened manually
|
||||
/// - no other device can access lock
|
||||
/// </remarks>
|
||||
public class DisposableOpen : Base, IRequestHandler, StartReservationCommand.IStartReservationCommandListener, CloseCommand.ICloseCommandListener
|
||||
{
|
||||
/// <summary> Bike is disposable, lock is open and can be reached via bluetooth. </summary>
|
||||
/// <remarks>
|
||||
/// This state should never occur because as long as a ILOCKIT is connected it
|
||||
/// - cannot be closed manually
|
||||
/// - no other device can access lock
|
||||
/// - app itself should never event attempt to open a lock which is not rented.
|
||||
/// </remarks>
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public DisposableOpen(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionRequestBike, // Reserve / Rent Bike
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionCloseLock; // Close Lock
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_startReservationOrRentalActionViewModel = new StartReservationOrRentalActionViewModel<DisposableOpen>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_closeLockActionViewModel = new CloseLockActionViewModel<DisposableOpen>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly StartReservationOrRentalActionViewModel<DisposableOpen> _startReservationOrRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the reserving a bike progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(StartReservationCommand.Step step) => _startReservationOrRentalActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the reserving a bike state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(StartReservationCommand.State state, string details) => await _startReservationOrRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly CloseLockActionViewModel<DisposableOpen> _closeLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CloseCommand.Step step) => _closeLockActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CloseCommand.State state, string details) => await _closeLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary>Rents bike by reserving bike and renting bike.</summary>
|
||||
/// <returns>Next request handler.</returns>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _startReservationOrRentalActionViewModel.StartReservationOrRentalAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary>Closes Lock.</summary>
|
||||
/// <returns>Next request handler.</returns>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _closeLockActionViewModel.CloseLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock
|
||||
{
|
||||
public interface IRequestHandler : IRequestHandlerBase
|
||||
{
|
||||
/// <summary> Gets a value indicating whether the ILockIt button which is managed by request handler is visible or not. </summary>
|
||||
bool IsLockitButtonVisible { get; }
|
||||
|
||||
/// <summary> Gets the text of the ILockIt button which is managed by request handler. </summary>
|
||||
string LockitButtonText { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs the copri action to be executed when user presses the copri button managed by request handler.
|
||||
/// </summary>
|
||||
/// <returns>New handler object if action succeeded, same handler otherwise.</returns>
|
||||
Task<IRequestHandler> HandleRequestOption1();
|
||||
|
||||
Task<IRequestHandler> HandleRequestOption2();
|
||||
|
||||
/// <summary>
|
||||
/// Holds error description (invalid state).
|
||||
/// </summary>
|
||||
string ErrorText { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.State;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class InvalidState : IRequestHandler
|
||||
{
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public InvalidState(
|
||||
IBikesViewModel bikesViewModel,
|
||||
InUseStateEnum copriState,
|
||||
LockingState lockingState,
|
||||
string errorText)
|
||||
{
|
||||
BikesViewModel = bikesViewModel
|
||||
?? throw new ArgumentException($"Can not construct {GetType().Name}-object. {nameof(bikesViewModel)} must not be null.");
|
||||
|
||||
ErrorText = errorText;
|
||||
|
||||
Log.Error($"{errorText}. Copri state is {copriState} and lock state is {lockingState}.");
|
||||
}
|
||||
|
||||
/// <summary>View model to be used for progress report and unlocking/ locking view.</summary>
|
||||
public IBikesViewModel BikesViewModel { get; }
|
||||
|
||||
public bool IsLockitButtonVisible => false;
|
||||
|
||||
public string LockitButtonText => GetType().Name;
|
||||
|
||||
public bool IsConnected => false;
|
||||
|
||||
public bool IsButtonVisible => false;
|
||||
|
||||
public string ButtonText => GetType().Name;
|
||||
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
public bool IsRemoveBikeRequired => false;
|
||||
|
||||
public string ErrorText { get; }
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
Log.ForContext<InvalidState>().Error($"Click of unsupported button {nameof(HandleRequestOption2)} detected.");
|
||||
return await Task.FromResult<IRequestHandler>(this);
|
||||
}
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
Log.ForContext<InvalidState>().Error($"Click of unsupported button {nameof(HandleRequestOption1)} detected.");
|
||||
return await Task.FromResult<IRequestHandler>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using ShareeBike.Model.State;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.View;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock
|
||||
{
|
||||
public class NotLoggedIn : IRequestHandler
|
||||
{
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public NotLoggedIn(
|
||||
InUseStateEnum state,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel)
|
||||
{
|
||||
ButtonText = BC.StateToText.GetActionText(state);
|
||||
ViewService = viewService;
|
||||
BikesViewModel = bikesViewModel
|
||||
?? throw new ArgumentException($"Can not construct {GetType().Name}-object. {nameof(bikesViewModel)} must not be null.");
|
||||
}
|
||||
|
||||
/// <summary>View model to be used for progress report and unlocking/ locking view.</summary>
|
||||
public IBikesViewModel BikesViewModel { get; }
|
||||
|
||||
public bool IsButtonVisible => true;
|
||||
|
||||
public bool IsLockitButtonVisible => false;
|
||||
|
||||
public string ButtonText { get; private set; }
|
||||
|
||||
public string LockitButtonText => GetType().Name;
|
||||
|
||||
/// <summary>
|
||||
/// Reference on view service to show modal notifications and to perform navigation.
|
||||
/// </summary>
|
||||
private IViewService ViewService { get; }
|
||||
|
||||
public bool IsConnected => throw new NotImplementedException();
|
||||
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
public bool IsRemoveBikeRequired => false;
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
Log.ForContext<BikesViewModel>().Information("User selected bike but is not logged in.");
|
||||
|
||||
// User is not logged in
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
var l_oResult = await ViewService.DisplayAlert(
|
||||
AppResources.QuestionLogInTitle,
|
||||
AppResources.QuestionLogIn,
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
if (l_oResult == false)
|
||||
{
|
||||
// User aborted booking process
|
||||
BikesViewModel.IsIdle = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Switch to map page
|
||||
await ViewService.ShowPage("//LoginPage");
|
||||
}
|
||||
catch (Exception p_oException)
|
||||
{
|
||||
Log.ForContext<BikesViewModel>().Error("Ein unerwarteter Fehler ist in der Klasse NotLoggedIn aufgetreten. Kontext: Aufruf nach Reservierungsversuch ohne Anmeldung. {@Exception}", p_oException);
|
||||
BikesViewModel.IsIdle = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
BikesViewModel.IsIdle = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
Log.ForContext<NotLoggedIn>().Error("Click of unsupported button detected.");
|
||||
return await Task.FromResult(this);
|
||||
}
|
||||
|
||||
public string ErrorText => string.Empty;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using IBikeInfoMutable = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable;
|
||||
using CancelReservationCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.CancelReservationCommand;
|
||||
using StartRentalCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartRentalCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
/// <summary> Bike is reserved, lock is closed and connected to app. </summary>
|
||||
/// <remarks>
|
||||
/// Occurs when
|
||||
/// - bike was reserved out of reach and is in reach now
|
||||
/// - bike is reserved while in reach
|
||||
/// </remarks>
|
||||
public class ReservedClosed : Base, IRequestHandler, CancelReservationCommand.ICancelReservationCommandListener, StartRentalCommand.IStartRentalCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public ReservedClosed(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionCancelReservation, // Cancel Reservation
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionOpenLockAndRentBike; // Rent Bike
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_cancelReservationActionViewModel = new CancelReservationActionViewModel<ReservedClosed>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_startRentalActionViewModel = new StartReservationOrRentalActionViewModel<ReservedClosed>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly CancelReservationActionViewModel<ReservedClosed> _cancelReservationActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the canceling of reservation progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CancelReservationCommand.Step step) => _cancelReservationActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the canceling of reservation state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CancelReservationCommand.State state, string details) => await _cancelReservationActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly StartReservationOrRentalActionViewModel<ReservedClosed> _startRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(StartRentalCommand.Step step) => _startRentalActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(StartRentalCommand.State state, string details) => await _startRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary> Cancel reservation. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _cancelReservationActionViewModel.CancelReservationAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary> Open lock and rent bike. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _startRentalActionViewModel.StartReservationOrRentalAsync();
|
||||
if (_startRentalActionViewModel.ContinueWithOpenLock == false)
|
||||
{
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
var _openLockActionViewModel = new OpenLockActionViewModel<BookedClosed>(
|
||||
SelectedBike,
|
||||
ViewUpdateManager,
|
||||
ViewService,
|
||||
BikesViewModel);
|
||||
|
||||
await _openLockActionViewModel.OpenLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using CancelReservationCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.CancelReservationCommand;
|
||||
using StartRentalCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartRentalCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class ReservedDisconnected : Base, IRequestHandler, CancelReservationCommand.ICancelReservationCommandListener, StartRentalCommand.IStartRentalCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public ReservedDisconnected(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionCancelReservation, // Cancel Reservation
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionRentBike; // Rent bike
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_cancelReservationlActionViewModel = new CancelReservationActionViewModel<ReservedDisconnected>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_startRentalActionViewModel = new StartReservationOrRentalActionViewModel<ReservedDisconnected>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly CancelReservationActionViewModel<ReservedDisconnected> _cancelReservationlActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the canceling of reservation progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CancelReservationCommand.Step step) => _cancelReservationlActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the canceling of reservation state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CancelReservationCommand.State state, string details) => await _cancelReservationlActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
/// <summary> Cancel reservation. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _cancelReservationlActionViewModel.CancelReservationAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly StartReservationOrRentalActionViewModel<ReservedDisconnected> _startRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(StartRentalCommand.Step step) => _startRentalActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(StartRentalCommand.State state, string details) => await _startRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary> Connect to reserved bike ask whether to rent bike or not and if yes open lock. </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _startRentalActionViewModel.StartReservationOrRentalAsync();
|
||||
if (_startRentalActionViewModel.ContinueWithOpenLock == false)
|
||||
{
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
var _openLockActionViewModel = new OpenLockActionViewModel<BookedClosed>(
|
||||
SelectedBike,
|
||||
ViewUpdateManager,
|
||||
ViewService,
|
||||
BikesViewModel);
|
||||
|
||||
await _openLockActionViewModel.OpenLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using IBikeInfoMutable = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable;
|
||||
using CloseCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand;
|
||||
using StartRentalCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartRentalCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
/// <summary> Bike is reserved, lock is open and connected to app. </summary>
|
||||
/// <remarks>
|
||||
/// This state might occur when a ILOCKIT was manually opened (color code) and app connects afterwards.
|
||||
/// This should never during ILOCKIT is connected to app because
|
||||
/// - manually opening lock is not possible when lock is connected
|
||||
/// - two devices can not simultaneously connect to same lock.
|
||||
public class ReservedOpen : Base, IRequestHandler, CloseCommand.ICloseCommandListener, StartRentalCommand.IStartRentalCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public ReservedOpen(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionCloseLock, // Close Lock
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionRentBike; // Rent bike
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_closeLockActionViewModel = new CloseLockActionViewModel<ReservedOpen>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_startRentalActionViewModel = new StartReservationOrRentalActionViewModel<ReservedOpen>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly CloseLockActionViewModel<ReservedOpen> _closeLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CloseCommand.Step step) => _closeLockActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CloseCommand.State state, string details) => await _closeLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly StartReservationOrRentalActionViewModel<ReservedOpen> _startRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(StartRentalCommand.Step step) => _startRentalActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(StartRentalCommand.State state, string details) => await _startRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary> Close lock. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _closeLockActionViewModel.CloseLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
/// <summary> Start Rental. </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _startRentalActionViewModel.StartReservationOrRentalAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.Device;
|
||||
using ShareeBike.Model.User;
|
||||
using ShareeBike.MultilingualResources;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.View;
|
||||
using CloseCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand;
|
||||
using StartRentalCommand = ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartRentalCommand;
|
||||
using static ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandlerFactory;
|
||||
|
||||
namespace ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class ReservedUnknown : Base, IRequestHandler, CloseCommand.ICloseCommandListener, StartRentalCommand.IStartRentalCommandListener
|
||||
{
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
public ReservedUnknown(
|
||||
IBikeInfoMutable selectedBike,
|
||||
Func<bool> isConnectedDelegate,
|
||||
Func<bool, IConnector> connectorFactory,
|
||||
IGeolocationService geolocation,
|
||||
ILocksService lockService,
|
||||
Func<IPollingUpdateTaskManager> viewUpdateManager,
|
||||
ISmartDevice smartDevice,
|
||||
IViewService viewService,
|
||||
IBikesViewModel bikesViewModel,
|
||||
IUser activeUser) : base(
|
||||
selectedBike,
|
||||
AppResources.ActionCloseLock, // Close Lock
|
||||
true, // Show button
|
||||
isConnectedDelegate,
|
||||
connectorFactory,
|
||||
geolocation,
|
||||
lockService,
|
||||
viewUpdateManager,
|
||||
smartDevice,
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser)
|
||||
{
|
||||
LockitButtonText = AppResources.ActionRentBike; // Rent Bike
|
||||
IsLockitButtonVisible = true; // Show button
|
||||
|
||||
_closeLockActionViewModel = new CloseLockActionViewModel<ReservedUnknown>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
|
||||
_startRentalActionViewModel = new StartReservationOrRentalActionViewModel<ReservedUnknown>(
|
||||
selectedBike,
|
||||
viewUpdateManager,
|
||||
viewService,
|
||||
bikesViewModel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for close action.
|
||||
/// </summary>
|
||||
private readonly CloseLockActionViewModel<ReservedUnknown> _closeLockActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(CloseCommand.Step step) => _closeLockActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the close lock state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(CloseCommand.State state, string details) => await _closeLockActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Holds the view model for requesting a bike action.
|
||||
/// </summary>
|
||||
private readonly StartReservationOrRentalActionViewModel<ReservedUnknown> _startRentalActionViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike progress.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="step">Current step to process.</param>
|
||||
public void ReportStep(StartRentalCommand.Step step) => _startRentalActionViewModel?.ReportStep(step);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the renting a bike state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only used for testing.
|
||||
/// </remarks>
|
||||
/// <param name="state">State to process.</param>
|
||||
/// <param name="details">Textual details describing current state.</param>
|
||||
public async Task ReportStateAsync(StartRentalCommand.State state, string details) => await _startRentalActionViewModel.ReportStateAsync(state, details);
|
||||
|
||||
/// <summary> Open bike and update COPRI lock state. </summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption2()
|
||||
{
|
||||
await _startRentalActionViewModel.StartReservationOrRentalAsync();
|
||||
if (_startRentalActionViewModel.ContinueWithOpenLock == false)
|
||||
{
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
|
||||
var _openLockActionViewModel = new OpenLockActionViewModel<BookedClosed>(
|
||||
SelectedBike,
|
||||
ViewUpdateManager,
|
||||
ViewService,
|
||||
BikesViewModel);
|
||||
|
||||
await _openLockActionViewModel.OpenLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
/// <summary> Close lock (and return bike).</summary>
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
{
|
||||
await _closeLockActionViewModel.CloseLockAsync();
|
||||
return Create(
|
||||
SelectedBike,
|
||||
IsConnectedDelegate,
|
||||
ConnectorFactory,
|
||||
GeolocationService,
|
||||
LockService,
|
||||
ViewUpdateManager,
|
||||
SmartDevice,
|
||||
ViewService,
|
||||
BikesViewModel,
|
||||
ActiveUser);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue