2022-09-20 13:51:55 +02:00
using System ;
2021-05-13 20:03:07 +02:00
using System.Threading.Tasks ;
2022-08-30 15:42:25 +02:00
using Serilog ;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock ;
2021-05-13 20:03:07 +02:00
using TINK.Model.Connector ;
2022-08-30 15:42:25 +02:00
using TINK.Model.Device ;
using TINK.Model.User ;
using TINK.MultilingualResources ;
2021-06-26 20:57:55 +02:00
using TINK.Repository.Exception ;
2021-05-13 20:03:07 +02:00
using TINK.Services.BluetoothLock ;
using TINK.Services.BluetoothLock.Exception ;
2022-08-30 15:42:25 +02:00
using TINK.Services.BluetoothLock.Tdo ;
2022-10-26 20:53:18 +02:00
using TINK.Services.CopriApi.Exception ;
2022-08-30 15:42:25 +02:00
using TINK.Services.Geolocation ;
using TINK.View ;
2021-05-13 20:03:07 +02:00
namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
{
2022-09-06 16:08:19 +02:00
public class DisposableDisconnected : Base , IRequestHandler
{
/// <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 ,
2023-04-05 15:02:10 +02:00
IGeolocationService geolocation ,
2022-09-06 16:08:19 +02:00
ILocksService lockService ,
Func < IPollingUpdateTaskManager > viewUpdateManager ,
ISmartDevice smartDevice ,
IViewService viewService ,
IBikesViewModel bikesViewModel ,
IUser activeUser ) : base (
selectedBike ,
2023-11-06 12:23:09 +01:00
AppResources . ActionReserveBike , // Reserve Bike
true , // Show button "Reserve Bike"
2022-09-06 16:08:19 +02:00
isConnectedDelegate ,
connectorFactory ,
geolocation ,
lockService ,
viewUpdateManager ,
smartDevice ,
viewService ,
bikesViewModel ,
activeUser )
{
LockitButtonText = GetType ( ) . Name ;
2023-11-06 12:23:09 +01:00
IsLockitButtonVisible = false ; // If bike is not reserved/ rented app can not connect to lock
2022-09-06 16:08:19 +02:00
}
2023-11-06 12:23:09 +01:00
/// <summary>Reserve bike, connect to lock, open lock and rent bike.</summary>
public async Task < IRequestHandler > HandleRequestOption1 ( ) = > await ReserveRentBikeAndOpenLock ( ) ;
2022-09-06 16:08:19 +02:00
public async Task < IRequestHandler > HandleRequestOption2 ( ) = > await UnsupportedRequest ( ) ;
2023-11-06 12:23:09 +01:00
/// <summary>Reserve and rent bike.</summary>
public async Task < IRequestHandler > ReserveRentBikeAndOpenLock ( )
2022-09-06 16:08:19 +02:00
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "User request to reserve bike {bikeId}." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . IsIdle = false ;
2022-09-20 13:51:55 +02:00
// Ask whether to really reserve bike?
2022-09-06 16:08:19 +02:00
var alertResult = await ViewService . DisplayAlert (
string . Empty ,
2023-06-06 12:00:24 +02:00
string . Format (
AppResources . QuestionReserveBike ,
SelectedBike . GetFullDisplayName ( ) ,
SelectedBike . TariffDescription ? . MaxReservationTimeSpan . TotalMinutes ? ? 0 ) ,
2022-09-06 16:08:19 +02:00
AppResources . MessageAnswerYes ,
AppResources . MessageAnswerNo ) ;
if ( alertResult = = false )
{
// User aborted booking process
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "User canceled request to reserve bike {bikeId}." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . IsIdle = true ;
return this ;
}
// Lock list to avoid multiple taps while copri action is pending.
BikesViewModel . ActionText = AppResources . ActivityTextOneMomentPlease ;
// Stop polling before requesting bike.
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StopAsync ( ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextReservingBike ;
IsConnected = IsConnectedDelegate ( ) ;
2023-11-06 12:23:09 +01:00
// reserve bike
2022-09-06 16:08:19 +02:00
try
{
await ConnectorFactory ( IsConnected ) . Command . DoReserve ( SelectedBike ) ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "User reserved bike {bikeId} successfully." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
}
catch ( Exception exception )
{
BikesViewModel . ActionText = string . Empty ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Request to reserve bike {bikeId} declined." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
if ( exception is BookingDeclinedException )
{
// Too many bikes booked.
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "Maximum count of bikes {exception.MaxBikesCount} already requested/ booked." , ( exception as BookingDeclinedException ) . MaxBikesCount ) ;
2022-09-06 16:08:19 +02:00
await ViewService . DisplayAlert (
2023-08-31 12:20:06 +02:00
AppResources . MessageHintTitle ,
string . Format ( AppResources . ErrorReservingBikeTooManyReservationsRentals , SelectedBike . Id , ( exception as BookingDeclinedException ) . MaxBikesCount ) ,
2022-09-06 16:08:19 +02:00
AppResources . MessageAnswerOk ) ;
}
2022-10-26 20:53:18 +02:00
else if ( exception is WebConnectFailureException
| | exception is RequestNotCachableException )
2022-09-06 16:08:19 +02:00
{
// Copri server is not reachable.
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "Copri server not reachable." ) ;
2022-09-06 16:08:19 +02:00
await ViewService . DisplayAlert (
2023-08-31 12:20:06 +02:00
AppResources . ErrorNoConnectionTitle ,
AppResources . ErrorNoWeb ,
2022-09-06 16:08:19 +02:00
AppResources . MessageAnswerOk ) ;
}
else
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "{@exception}" , exception ) ;
2022-09-06 16:08:19 +02:00
2023-08-31 12:20:06 +02:00
await ViewService . DisplayAdvancedAlert (
AppResources . ErrorReservingBikeTitle ,
2022-09-06 16:08:19 +02:00
exception . Message ,
2023-08-31 12:20:06 +02:00
AppResources . ErrorTryAgain ,
2022-09-06 16:08:19 +02:00
AppResources . MessageAnswerOk ) ;
}
// Restart polling again.
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdater ;
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StartAsync ( ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = string . Empty ;
BikesViewModel . IsIdle = true ;
return this ;
}
// Search for lock.
LockInfoTdo result = null ;
BikesViewModel . ActionText = AppResources . ActivityTextSearchingLock ;
try
{
result = await LockService . ConnectAsync (
new LockInfoAuthTdo . Builder { Id = SelectedBike . LockInfo . Id , Guid = SelectedBike . LockInfo . Guid , K_seed = SelectedBike . LockInfo . Seed , K_u = SelectedBike . LockInfo . UserKey } . Build ( ) ,
LockService . TimeOut . GetSingleConnect ( 1 ) ) ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Connected to lock of bike {bikeId} successfully. Value is {lockState}." , SelectedBike . Id , SelectedBike . LockInfo . State ) ;
2022-09-06 16:08:19 +02:00
}
catch ( Exception exception )
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Connection to lock of bike {bikeId} failed." ) ;
2022-09-06 16:08:19 +02:00
// Do not display any messages here, because search is implicit.
if ( exception is OutOfReachException )
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "Lock is out of reach." ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextLockIsOutOfReach ;
}
else
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "{@exception}" , exception ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextLockNotFound ;
}
// Restart polling again.
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdater ;
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StartAsync ( ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = string . Empty ;
BikesViewModel . IsIdle = true ;
2023-04-05 15:02:10 +02:00
return RequestHandlerFactory . Create ( SelectedBike , IsConnectedDelegate , ConnectorFactory , GeolocationService , LockService , ViewUpdateManager , SmartDevice , ViewService , BikesViewModel , ActiveUser ) ;
2022-09-06 16:08:19 +02:00
}
2023-11-06 12:23:09 +01:00
// get current locking state
2022-09-06 16:08:19 +02:00
SelectedBike . LockInfo . State = result ? . State ? . GetLockingState ( ) ? ? LockingState . UnknownDisconnected ;
if ( SelectedBike . LockInfo . State = = LockingState . UnknownDisconnected )
{
// Do not display any messages here, because search is implicit.
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "Lock is still not connected." ) ;
2022-09-06 16:08:19 +02:00
// Restart polling again.
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdater ;
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StartAsync ( ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = string . Empty ;
BikesViewModel . IsIdle = true ;
2023-04-05 15:02:10 +02:00
return RequestHandlerFactory . Create ( SelectedBike , IsConnectedDelegate , ConnectorFactory , GeolocationService , LockService , ViewUpdateManager , SmartDevice , ViewService , BikesViewModel , ActiveUser ) ;
2022-09-06 16:08:19 +02:00
}
SelectedBike . LockInfo . Guid = result ? . Guid ? ? new Guid ( ) ;
// Ask whether to really book bike?
2023-11-06 12:23:09 +01:00
alertResult = SelectedBike . LockInfo . State ! = LockingState . Open
? await ViewService . DisplayAlert (
string . Empty ,
string . Format ( AppResources . QuestionOpenLockAndBookBike , SelectedBike . GetFullDisplayName ( ) ) ,
AppResources . MessageAnswerYes ,
AppResources . MessageAnswerNo )
: await ViewService . DisplayAlert (
string . Empty ,
string . Format ( AppResources . QuestionBookBike , SelectedBike . GetFullDisplayName ( ) ) ,
AppResources . MessageAnswerYes ,
AppResources . MessageAnswerNo ) ;
2022-09-06 16:08:19 +02:00
if ( alertResult = = false )
{
// User aborted booking process
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "User request to not book reserved bike {bikeId}." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
// Disconnect lock.
BikesViewModel . ActionText = AppResources . ActivityTextDisconnectingLock ;
try
{
SelectedBike . LockInfo . State = await LockService . DisconnectAsync ( SelectedBike . LockInfo . Id , SelectedBike . LockInfo . Guid ) ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Disconnected from lock of bike {bikeId} successfully." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
}
catch ( Exception exception )
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Lock of bike {bikeId} can not be disconnected. {@exception}" , SelectedBike . Id , exception ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextErrorDisconnect ;
}
// Restart polling again.
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdater ;
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StartAsync ( ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = string . Empty ;
BikesViewModel . IsIdle = true ;
2023-04-05 15:02:10 +02:00
return RequestHandlerFactory . Create ( SelectedBike , IsConnectedDelegate , ConnectorFactory , GeolocationService , LockService , ViewUpdateManager , SmartDevice , ViewService , BikesViewModel , ActiveUser ) ;
2022-09-06 16:08:19 +02:00
}
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "User request to book reserved bike {bikeId}." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
// Book bike prior to opening lock.
BikesViewModel . ActionText = AppResources . ActivityTextRentingBike ;
IsConnected = IsConnectedDelegate ( ) ;
try
{
2023-11-06 12:23:09 +01:00
if ( SelectedBike . LockInfo . State ! = LockingState . Open )
{
await ConnectorFactory ( IsConnected ) . Command . DoBookAsync ( SelectedBike , LockingAction . Open ) ;
}
else
{
await ConnectorFactory ( IsConnected ) . Command . DoBookAsync ( SelectedBike ) ;
}
Log . ForContext < DisposableDisconnected > ( ) . Information ( "User booked bike {bikeId} successfully." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
}
2023-11-06 12:23:09 +01:00
catch ( Exception exception )
2022-09-06 16:08:19 +02:00
{
BikesViewModel . ActionText = string . Empty ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Booking of bike {bikeId} failed." , SelectedBike . Id ) ;
if ( exception is WebConnectFailureException )
2022-09-06 16:08:19 +02:00
{
// Copri server is not reachable.
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "Copri server not reachable." ) ;
2022-09-06 16:08:19 +02:00
2023-08-31 12:20:06 +02:00
await ViewService . DisplayAlert (
AppResources . ErrorNoConnectionTitle ,
AppResources . ErrorNoWeb ,
2022-09-06 16:08:19 +02:00
AppResources . MessageAnswerOk ) ;
}
else
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "{@exception}" , exception ) ;
2022-09-06 16:08:19 +02:00
2023-08-31 12:20:06 +02:00
await ViewService . DisplayAlert (
AppResources . ErrorRentingBikeTitle ,
2023-11-06 12:23:09 +01:00
exception . Message ,
2022-09-06 16:08:19 +02:00
AppResources . MessageAnswerOk ) ;
}
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdater ;
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StartAsync ( ) ; // Restart polling again.
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = string . Empty ;
BikesViewModel . IsIdle = true ; // Unlock GUI
2023-04-05 15:02:10 +02:00
return RequestHandlerFactory . Create ( SelectedBike , IsConnectedDelegate , ConnectorFactory , GeolocationService , LockService , ViewUpdateManager , SmartDevice , ViewService , BikesViewModel , ActiveUser ) ;
2022-09-06 16:08:19 +02:00
}
// Unlock bike.
2023-11-06 12:23:09 +01:00
ILockService btLock = LockService [ SelectedBike . LockInfo . Id ] ;
if ( SelectedBike . LockInfo . State ! = LockingState . Open )
2022-09-06 16:08:19 +02:00
{
2023-11-06 12:23:09 +01:00
BikesViewModel . ActionText = AppResources . ActivityTextOpeningLock ;
try
2022-09-06 16:08:19 +02:00
{
2023-11-06 12:23:09 +01:00
SelectedBike . LockInfo . State = ( await btLock . OpenAsync ( ) ) ? . GetLockingState ( ) ? ? LockingState . UnknownDisconnected ;
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Lock from {bikeId} opened successfully." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
}
2023-11-06 12:23:09 +01:00
catch ( Exception exception )
2022-09-06 16:08:19 +02:00
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Lock from {bikeId} can not be opened." , SelectedBike . Id ) ;
BikesViewModel . ActionText = string . Empty ;
if ( exception is OutOfReachException )
{
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "Lock is out of reach." ) ;
await ViewService . DisplayAlert (
AppResources . ErrorOpenLockTitle ,
AppResources . ErrorLockOutOfReach ,
AppResources . MessageAnswerOk ) ;
}
else if ( exception is CouldntOpenBoldIsBlockedException )
{
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "Bold is blocked." ) ;
await ViewService . DisplayAlert (
AppResources . ErrorOpenLockTitle ,
AppResources . ErrorOpenLockBoldBlocked ,
AppResources . MessageAnswerOk ) ;
}
else if ( exception is CouldntOpenBoldStatusIsUnknownException )
{
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "Bold status is unknown." ) ;
await ViewService . DisplayAlert (
AppResources . ErrorOpenLockTitle ,
AppResources . ErrorOpenLockStatusUnknown ,
AppResources . MessageAnswerOk ) ;
}
else if ( exception is CouldntOpenInconsistentStateExecption inconsistentState
& & inconsistentState . State = = LockingState . Closed )
{
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "Lock reports that it is still closed." ) ;
await ViewService . DisplayAlert (
AppResources . ErrorOpenLockTitle ,
AppResources . ErrorOpenLockStillClosed ,
AppResources . MessageAnswerOk ) ;
}
else
{
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "{@exception}" , exception ) ;
await ViewService . DisplayAdvancedAlert (
AppResources . ErrorOpenLockTitle ,
AppResources . ErrorTryAgain ,
exception . Message ,
AppResources . MessageAnswerOk ) ;
}
SelectedBike . LockInfo . State = exception is StateAwareException stateAwareException
? stateAwareException . State
: LockingState . UnknownDisconnected ;
2022-09-06 16:08:19 +02:00
}
}
2023-11-06 12:23:09 +01:00
// get current charging level
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextReadingChargingLevel ;
try
{
2022-09-20 13:51:55 +02:00
SelectedBike . LockInfo . BatteryPercentage = await btLock . GetBatteryPercentageAsync ( ) ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Battery state of lock from {bikeId} read successfully." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
}
catch ( Exception exception )
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Battery state of lock from {bikeId} can not be read." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
if ( exception is OutOfReachException )
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "Lock is out of reach" ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextErrorReadingChargingLevelOutOfReach ;
}
else
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Error ( "{@exception}" , exception ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextErrorReadingChargingLevelGeneral ;
}
}
2023-11-06 12:23:09 +01:00
// Get lock infos.
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdatingLockingState ;
2022-09-20 13:51:55 +02:00
var versionTdo = btLock . VersionInfo ;
if ( versionTdo ! = null )
{
SelectedBike . LockInfo . VersionInfo = new VersionInfo . Builder
{
FirmwareVersion = versionTdo . FirmwareVersion ,
HardwareVersion = versionTdo . HardwareVersion ,
LockVersion = versionTdo . LockVersion ,
} . Build ( ) ;
}
2022-09-06 16:08:19 +02:00
2023-11-06 12:23:09 +01:00
// update backend
IsConnected = IsConnectedDelegate ( ) ;
2022-09-06 16:08:19 +02:00
try
{
await ConnectorFactory ( IsConnected ) . Command . UpdateLockingStateAsync ( SelectedBike ) ;
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Backend updated for bike {bikeId} successfully." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
}
catch ( Exception exception )
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Information ( "Updating backend for bike {bikeId} failed." , SelectedBike . Id ) ;
2022-09-06 16:08:19 +02:00
if ( exception is WebConnectFailureException )
{
2023-11-06 12:23:09 +01:00
// No web.
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "Copri server not reachable. No web." ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextErrorNoWebUpdateingLockstate ;
}
else if ( exception is ResponseException copriException )
{
2023-11-06 12:23:09 +01:00
// Copri exception.
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "{response}" , copriException . Response ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextErrorStatusUpdateingLockstate ;
}
else
{
2023-11-06 12:23:09 +01:00
Log . ForContext < DisposableDisconnected > ( ) . Debug ( "{@exception}" , exception ) ;
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = AppResources . ActivityTextErrorConnectionUpdateingLockstate ;
}
}
BikesViewModel . ActionText = AppResources . ActivityTextStartingUpdater ;
2023-08-31 12:20:06 +02:00
await ViewUpdateManager ( ) . StartAsync ( ) ; // Restart polling again.
2022-09-06 16:08:19 +02:00
BikesViewModel . ActionText = string . Empty ;
BikesViewModel . IsIdle = true ; // Unlock GUI
2023-04-05 15:02:10 +02:00
return RequestHandlerFactory . Create ( SelectedBike , IsConnectedDelegate , ConnectorFactory , GeolocationService , LockService , ViewUpdateManager , SmartDevice , ViewService , BikesViewModel , ActiveUser ) ;
2022-09-06 16:08:19 +02:00
}
2023-04-19 12:14:14 +02:00
/// <summary> Request is not supported, button should be disabled. </summary>
2022-09-06 16:08:19 +02:00
/// <returns></returns>
public async Task < IRequestHandler > UnsupportedRequest ( )
{
Log . ForContext < DisposableDisconnected > ( ) . Error ( "Click of unsupported button click detected." ) ;
return await Task . FromResult < IRequestHandler > ( this ) ;
}
}
2021-05-13 20:03:07 +02:00
}