mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-21 21:46:27 +02:00
Version 3.0.373
This commit is contained in:
parent
f1cbab1d0a
commit
06428d96d9
87 changed files with 1796 additions and 1208 deletions
|
@ -273,8 +273,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
|
|||
var feedBackUri = SelectedBike?.OperatorUri;
|
||||
var battery = SelectedBike.Drive?.Battery;
|
||||
var feedback = await ViewService.DisplayUserFeedbackPopup(
|
||||
battery,
|
||||
bookingFinished?.Co2Saving);
|
||||
battery);
|
||||
|
||||
if (battery != null
|
||||
&& feedback.CurrentChargeBars != null)
|
||||
|
@ -350,11 +349,20 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
|
|||
await ViewService.DisplayAlert(
|
||||
String.Format(AppResources.MessageRentalProcessEndRentalFinishedTitle, SelectedBike.Id),
|
||||
String.Format(
|
||||
"{0}{1}",
|
||||
!string.IsNullOrWhiteSpace(bookingFinished?.Co2Saving) ?
|
||||
$"{bookingFinished?.Co2Saving}\r\n\r\n"
|
||||
"{0}{1}{2}{3}{4}",
|
||||
!string.IsNullOrWhiteSpace(bookingFinished?.Distance) ?
|
||||
$"{String.Format(AppResources.MessageRentalProcessEndRentalFinishedDistanceText, bookingFinished?.Distance)}\r\n"
|
||||
: string.Empty,
|
||||
String.Format(AppResources.MessageRentalProcessEndRentalFinishedText)
|
||||
!string.IsNullOrWhiteSpace(bookingFinished?.Co2Saving) ?
|
||||
$"{String.Format(AppResources.MessageRentalProcessEndRentalFinishedCO2SavingText, bookingFinished?.Co2Saving)}\r\n"
|
||||
: string.Empty,
|
||||
!string.IsNullOrWhiteSpace(bookingFinished?.Duration) ?
|
||||
$"{String.Format(AppResources.MessageRentalProcessEndRentalFinishedDurationText, bookingFinished?.Duration)}\r\n"
|
||||
: $"{string.Empty}",
|
||||
!string.IsNullOrWhiteSpace(bookingFinished?.RentalCosts) ?
|
||||
$"{String.Format(AppResources.MessageRentalProcessEndRentalFinishedRentalCostsText,bookingFinished?.RentalCosts)}\r\n"
|
||||
: $"{AppResources.MessageRentalProcessEndRentalFinishedNoRentalCostsText}\r\n",
|
||||
AppResources.MessageRentalProcessEndRentalFinishedText
|
||||
),
|
||||
AppResources.MessageAnswerOk
|
||||
);
|
||||
|
|
|
@ -64,8 +64,7 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
// Do get Feedback
|
||||
var battery = SelectedBike.Drive?.Battery;
|
||||
var feedback = await ViewService.DisplayUserFeedbackPopup(
|
||||
battery,
|
||||
SelectedBike?.BookingFinishedModel?.Co2Saving);
|
||||
battery);
|
||||
|
||||
if (battery != null
|
||||
&& feedback.CurrentChargeBars != null)
|
||||
|
|
|
@ -6,7 +6,6 @@ using System.Windows.Input;
|
|||
using Plugin.Messaging;
|
||||
using Serilog;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Stations;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
using TINK.MultilingualResources;
|
||||
using TINK.View;
|
||||
|
@ -90,25 +89,23 @@ namespace TINK.ViewModel.Info
|
|||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PhoneNumberText)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ProviderNameText)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsOperatorInfoAvaliable)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsDoPhoncallAvailable)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSendMailAvailable)));
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary> Command object to bind mail button to view model. </summary>
|
||||
public ICommand OnMailToOperatorRequest
|
||||
=> new Command(
|
||||
async () => await DoSendMailToOperator(),
|
||||
() => IsSendMailAvailable);
|
||||
=> new Command(async () => await DoSendMailToOperator());
|
||||
|
||||
/// <summary> Command object to bind mail app related button to model. </summary>
|
||||
public ICommand OnMailAppRelatedRequest
|
||||
=> new Command(
|
||||
async () => await DoSendMailAppRelated(),
|
||||
() => IsSendMailAvailable);
|
||||
=> new Command(async () => await DoSendMailAppRelated());
|
||||
|
||||
/// <summary>True if sending mail is possible.</summary>
|
||||
public bool IsSendMailAvailable =>
|
||||
CrossMessaging.Current.EmailMessenger.CanSendEmail;
|
||||
public bool IsSendMailAvailable
|
||||
=> CrossMessaging.Current.EmailMessenger.CanSendEmail;
|
||||
|
||||
|
||||
/// <summary>cTrue if doing a phone call is possible.</summary>
|
||||
|
@ -134,91 +131,107 @@ namespace TINK.ViewModel.Info
|
|||
/// <returns> Returns true if either mail was sent or if no mailer available.</returns>
|
||||
public async Task DoSendMailToOperator()
|
||||
{
|
||||
try
|
||||
if (!IsSendMailAvailable)
|
||||
{
|
||||
if (!IsSendMailAvailable)
|
||||
{
|
||||
// Nothing to do because email can not be sent.
|
||||
return;
|
||||
}
|
||||
|
||||
// Send operator related support mail to operator.
|
||||
await Email.ComposeAsync(new EmailMessage
|
||||
{
|
||||
To = new List<string> { MailAddressText },
|
||||
Cc = APPSUPPORTMAILADDRESS.ToUpper() != MailAddressText.ToUpper() // do not sent copy if same mail address
|
||||
&& MailAddressText != "konrad@sharee.bike" // do not sent copy if Mein konrad
|
||||
? new List<string> { APPSUPPORTMAILADDRESS } : new List<string>(),
|
||||
Subject = string.Format(AppResources.SupportmailSubjectOperatormail, AppFlavorName, SelectedStation?.Id),
|
||||
Body = TinkApp.ActiveUser.Mail != null ? $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.MarkingLoggedInStateInfoLoggedIn, TinkApp.ActiveUser.Mail)}" : $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.SupportmailBodyNotLoggedIn)}"
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("An unexpected error occurred sending mail to operator. {@Exception}", exception);
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
await ViewService.DisplayAlert(
|
||||
String.Empty,
|
||||
AppResources.ErrorSupportmailMailingFailed,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Send operator related support mail to operator.
|
||||
await Email.ComposeAsync(new EmailMessage
|
||||
{
|
||||
To = new List<string> { MailAddressText },
|
||||
Cc = APPSUPPORTMAILADDRESS.ToUpper() != MailAddressText.ToUpper() // do not sent copy if same mail address
|
||||
&& MailAddressText != "konrad@sharee.bike" // do not sent copy if Mein konrad
|
||||
? new List<string> { APPSUPPORTMAILADDRESS } : new List<string>(),
|
||||
Subject = string.Format(AppResources.SupportmailSubjectOperatormail, AppFlavorName, SelectedStation?.Id),
|
||||
Body = TinkApp.ActiveUser.Mail != null ? $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.MarkingLoggedInStateInfoLoggedIn, TinkApp.ActiveUser.Mail)}" : $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.SupportmailBodyNotLoggedIn)}"
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("An unexpected error occurred sending mail to operator. {@Exception}", exception);
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.ErrorSupportmailMailingFailed,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Request to send a app related mail. </summary>
|
||||
public async Task DoSendMailAppRelated()
|
||||
{
|
||||
try
|
||||
if (!IsSendMailAvailable)
|
||||
{
|
||||
// Ask for permission to append diagnostics.
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.QuestionSupportmailAttachmentTitle,
|
||||
AppResources.QuestionSupportmailAttachment,
|
||||
String.Empty,
|
||||
AppResources.ErrorSupportmailMailingFailed,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
var message = new EmailMessage
|
||||
{
|
||||
To = new List<string> { APPSUPPORTMAILADDRESS },
|
||||
Subject = SelectedStation?.Id != null ? string.Format(AppResources.SupportmailSubjectAppmailWithStation, AppFlavorName, SelectedStation?.Id) : string.Format(AppResources.SupportmailSubjectAppmail, AppFlavorName),
|
||||
Body = TinkApp.ActiveUser.Mail != null ? $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.MarkingLoggedInStateInfoLoggedIn, TinkApp.ActiveUser.Mail)}" : $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.SupportmailBodyNotLoggedIn)}"
|
||||
};
|
||||
|
||||
// Send with attachment.
|
||||
var logFileName = string.Empty;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
logFileName = CreateAttachment();
|
||||
// Ask for permission to append diagnostics.
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.QuestionSupportmailAttachmentTitle,
|
||||
AppResources.QuestionSupportmailAttachment,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
var message = new EmailMessage
|
||||
{
|
||||
To = new List<string> { APPSUPPORTMAILADDRESS },
|
||||
Subject = SelectedStation?.Id != null ? string.Format(AppResources.SupportmailSubjectAppmailWithStation, AppFlavorName, SelectedStation?.Id) : string.Format(AppResources.SupportmailSubjectAppmail, AppFlavorName),
|
||||
Body = TinkApp.ActiveUser.Mail != null ? $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.MarkingLoggedInStateInfoLoggedIn, TinkApp.ActiveUser.Mail)}" : $"{AppResources.SupportmailBodyText}\r\n\r\n\r\n\r\n{string.Format(AppResources.SupportmailBodyNotLoggedIn)}"
|
||||
};
|
||||
|
||||
// Send with attachment.
|
||||
var logFileName = string.Empty;
|
||||
try
|
||||
{
|
||||
logFileName = CreateAttachment();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.ErrorSupportmailCreateAttachment,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<ContactPageViewModel>().Error("An error occurred creating attachment for app mail. {@Exception)", exception);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(logFileName))
|
||||
{
|
||||
message.Attachments.Add(new Xamarin.Essentials.EmailAttachment(logFileName));
|
||||
}
|
||||
|
||||
// Send a tink app related mail
|
||||
await Email.ComposeAsync(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ContactPageViewModel>().Error("An unexpected error occurred sending mail. {@Exception}", exception);
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.ErrorSupportmailCreateAttachment,
|
||||
AppResources.ErrorSupportmailMailingFailed,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<ContactPageViewModel>().Error("An error occurred creating attachment for app mail. {@Exception)", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(logFileName))
|
||||
{
|
||||
message.Attachments.Add(new Xamarin.Essentials.EmailAttachment(logFileName));
|
||||
}
|
||||
|
||||
// Send a tink app related mail
|
||||
await Email.ComposeAsync(message);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ContactPageViewModel>().Error("An unexpected error occurred sending mail. {@Exception}", exception);
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.ErrorSupportmailMailingFailed,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,31 +270,37 @@ namespace TINK.ViewModel.Info
|
|||
|
||||
/// <summary> Command object to bind phone call button. </summary>
|
||||
public ICommand OnPhoneRequest
|
||||
=> new Command(
|
||||
async () => await DoPhoneCall(),
|
||||
() => IsDoPhoncallAvailable);
|
||||
=> new Command(async () => await DoPhoneCall());
|
||||
|
||||
/// <summary> Request to do a phone call. </summary>
|
||||
public async Task DoPhoneCall()
|
||||
{
|
||||
try
|
||||
if (!IsDoPhoncallAvailable)
|
||||
{
|
||||
// Make Phone Call
|
||||
if (IsDoPhoncallAvailable)
|
||||
{
|
||||
CrossMessaging.Current.PhoneDialer.MakePhoneCall(PhoneNumberText);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("An unexpected error occurred doing a phone call. {@Exception}", exception);
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
await ViewService.DisplayAlert(
|
||||
String.Empty,
|
||||
AppResources.ErrorSupportmailPhoningFailed,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Make Phone Call
|
||||
CrossMessaging.Current.PhoneDialer.MakePhoneCall(PhoneNumberText);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error("An unexpected error occurred doing a phone call. {@Exception}", exception);
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.ErrorSupportmailPhoningFailed,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Text providing the id of the selected station.</summary>
|
||||
|
|
|
@ -13,10 +13,8 @@ using TINK.Model.Bikes;
|
|||
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Connector.Filter;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.State;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
using TINK.Model.User;
|
||||
using TINK.MultilingualResources;
|
||||
|
@ -29,7 +27,6 @@ using TINK.Settings;
|
|||
using TINK.View;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Map;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using Command = Xamarin.Forms.Command;
|
||||
|
||||
|
@ -77,7 +74,7 @@ namespace TINK.ViewModel.FindBike
|
|||
public BikeCollection Bikes { get; set; }
|
||||
|
||||
/// <summary> Do not allow to select bike if id is not set.</summary>
|
||||
public bool IsSelectBikeEnabled => IsIdle && BikeIdUserInput != null && BikeIdUserInput.Length > 0;
|
||||
public bool IsSelectBikeEnabled => IsIdle && BikeIdUserInput != null && BikeIdUserInput.Length > 1 && BikeIdUserInput.Any(x => char.IsLetter(x)) && BikeIdUserInput.Any(x => char.IsDigit(x));
|
||||
|
||||
/// <summary> Hide id input fields as soon as bike is found.</summary>
|
||||
public bool IsSelectBikeVisible => BikeCollection != null && BikeCollection.Count == 0;
|
||||
|
@ -85,6 +82,9 @@ namespace TINK.ViewModel.FindBike
|
|||
/// <summary> Holds the stations to get station names form station ids. </summary>
|
||||
private IEnumerable<IStation> Stations { get; }
|
||||
|
||||
/// <summary> Reference on the tink app instance. </summary>
|
||||
private ITinkApp TinkApp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if ListView of Bikes is refreshing after user pulled;
|
||||
/// </summary>
|
||||
|
@ -124,6 +124,7 @@ namespace TINK.ViewModel.FindBike
|
|||
/// <param name="openUrlInBrowser">Delegate to open browser.</param>
|
||||
public FindBikePageViewModel(
|
||||
User user,
|
||||
ITinkApp tinkApp,
|
||||
ILocationPermission permissions,
|
||||
IBluetoothLE bluetoothLE,
|
||||
string runtimPlatform,
|
||||
|
@ -145,6 +146,9 @@ namespace TINK.ViewModel.FindBike
|
|||
|
||||
Stations = stations ?? throw new ArgumentException(nameof(stations));
|
||||
|
||||
TinkApp = tinkApp
|
||||
?? throw new ArgumentException("Can not instantiate settings page view model- object. No tink app object available.");
|
||||
|
||||
RefreshCommand = new Command(async () => {
|
||||
|
||||
IsRefreshing = false;
|
||||
|
@ -215,99 +219,136 @@ namespace TINK.ViewModel.FindBike
|
|||
}
|
||||
|
||||
/// <summary> Command object to bind select bike button to view model. </summary>
|
||||
public System.Windows.Input.ICommand OnSelectBikeRequest => new Xamarin.Forms.Command(async () => await SelectBike(), () => IsSelectBikeEnabled);
|
||||
public System.Windows.Input.ICommand OnSelectBikeRequest => new Xamarin.Forms.Command(async () => await SelectBike());
|
||||
|
||||
/// <summary> Select a bike by ID</summary>
|
||||
public async Task SelectBike()
|
||||
{
|
||||
// Get List of bike to be able to connect to.
|
||||
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
|
||||
IsIdle = false;
|
||||
|
||||
IsConnected = IsConnectedDelegate();
|
||||
|
||||
Result<BikeCollection> bikes = null;
|
||||
try
|
||||
if (!IsSelectBikeEnabled)
|
||||
{
|
||||
bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exception is WebConnectFailureException)
|
||||
{
|
||||
// Copri server is not reachable.
|
||||
Log.ForContext<FindBikePageViewModel>().Information("Getting bikes failed (Copri server not reachable).");
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
AppResources.ErrorNoWeb,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bikes failed. {Exception}", exception);
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
await ViewService.DisplayAlert(
|
||||
String.Empty,
|
||||
AppResources.ErrorSelectBikeInputNotSufficent,
|
||||
AppResources.MessageAnswerOk);
|
||||
return;
|
||||
}
|
||||
finally
|
||||
else
|
||||
{
|
||||
Exception = bikes?.Exception ?? null; // Update communication error from query for bikes occupied.
|
||||
Bikes = bikes.Response;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var selectedBike = Bikes.FirstOrDefault(x => x.Id.Equals(BikeIdUserInput.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
// Get List of bike to be able to connect to.
|
||||
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
|
||||
IsIdle = false;
|
||||
|
||||
if (selectedBike == null)
|
||||
IsConnected = IsConnectedDelegate();
|
||||
|
||||
Result<BikeCollection> bikes = null;
|
||||
try
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
string.Format(AppResources.ErrorSelectBikeNoBikeFound, BikeIdUserInput),
|
||||
AppResources.MessageAnswerOk);
|
||||
bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exception is WebConnectFailureException)
|
||||
{
|
||||
// Copri server is not reachable.
|
||||
Log.ForContext<FindBikePageViewModel>().Information("Getting bikes failed (Copri server not reachable).");
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
AppResources.ErrorNoWeb,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bikes failed. {Exception}", exception);
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var bikeCollection = new BikeCollection(new Dictionary<string, Model.Bikes.BikeInfoNS.BC.BikeInfo> { { selectedBike.Id, selectedBike } });
|
||||
|
||||
var lockIdList = bikeCollection
|
||||
.GetLockIt()
|
||||
.Cast<BikeInfo>()
|
||||
.Select(x => x.LockInfo)
|
||||
.ToList();
|
||||
|
||||
if (LockService is ILocksServiceFake serviceFake)
|
||||
finally
|
||||
{
|
||||
serviceFake.UpdateSimulation(bikeCollection);
|
||||
Exception = bikes?.Exception ?? null; // Update communication error from query for bikes occupied.
|
||||
Bikes = bikes.Response;
|
||||
}
|
||||
|
||||
// Check bluetooth and location permission and states
|
||||
ActionText = AppResources.ActivityTextCheckBluetoothState;
|
||||
|
||||
if (bikeCollection.FirstOrDefault(x => x is BikeInfo btBike) != null
|
||||
//&& RuntimePlatform == Device.Android
|
||||
)
|
||||
try
|
||||
{
|
||||
// Check location permission
|
||||
var status = await PermissionsService.CheckStatusAsync();
|
||||
if (status != Status.Granted)
|
||||
{
|
||||
if (RuntimePlatform == Device.Android)
|
||||
{
|
||||
var permissionResult = await PermissionsService.RequestAsync();
|
||||
var selectedBike = Bikes.FirstOrDefault(x => x.Id.Equals(BikeIdUserInput.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (permissionResult != Status.Granted)
|
||||
if (selectedBike == null)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
TinkApp.Flavor == AppFlavor.MeinKonrad
|
||||
? $"{string.Format(AppResources.ErrorSelectBikeNoBikeFound, BikeIdUserInput)}\r\n\r\n{string.Format(AppResources.ErrorSelectBikeNoBikeFoundBikeTypeHint, ActiveFilteredBikeType)}"
|
||||
: string.Format(AppResources.ErrorSelectBikeNoBikeFound, BikeIdUserInput),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var bikeCollection = new BikeCollection(new Dictionary<string, Model.Bikes.BikeInfoNS.BC.BikeInfo> { { selectedBike.Id, selectedBike } });
|
||||
|
||||
var lockIdList = bikeCollection
|
||||
.GetLockIt()
|
||||
.Cast<BikeInfo>()
|
||||
.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.CheckStatusAsync();
|
||||
if (status != Status.Granted)
|
||||
{
|
||||
if (RuntimePlatform == Device.Android)
|
||||
{
|
||||
var permissionResult = await PermissionsService.RequestAsync();
|
||||
|
||||
if (permissionResult != Status.Granted)
|
||||
{
|
||||
var dialogResult = await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
AppResources.MessageBikesManagementLocationPermissionOpenDialog,
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
if (!dialogResult)
|
||||
{
|
||||
// User decided not to give access to locations permissions.
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Open permissions dialog.
|
||||
PermissionsService.OpenAppSettings();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var dialogResult = await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
|
@ -331,102 +372,79 @@ namespace TINK.ViewModel.FindBike
|
|||
PermissionsService.OpenAppSettings();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Location state
|
||||
if (GeolocationService.IsGeolcationEnabled == false)
|
||||
{
|
||||
var dialogResult = await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
AppResources.MessageBikesManagementLocationPermissionOpenDialog,
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
AppResources.MessageBikesManagementLocationActivation,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
if (!dialogResult)
|
||||
{
|
||||
// User decided not to give access to locations permissions.
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Open permissions dialog.
|
||||
PermissionsService.OpenAppSettings();
|
||||
// Bluetooth state
|
||||
if (await BluetoothService.GetBluetoothState() != BluetoothState.On)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
AppResources.MessageBikesManagementBluetoothActivation,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Location state
|
||||
if (GeolocationService.IsGeolcationEnabled == false)
|
||||
// Connect to bluetooth devices.
|
||||
ActionText = AppResources.ActivityTextSearchBikes;
|
||||
IEnumerable<LockInfoTdo> locksInfoTdo;
|
||||
try
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
AppResources.MessageBikesManagementLocationActivation,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
locksInfoTdo = await LockService.GetLocksStateAsync(
|
||||
lockIdList.Select(x => x.ToLockInfoTdo()).ToList(),
|
||||
LockService.TimeOut.MultiConnect);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bluetooth state failed. {Exception}", exception);
|
||||
locksInfoTdo = new List<LockInfoTdo>();
|
||||
}
|
||||
|
||||
// Bluetooth state
|
||||
if (await BluetoothService.GetBluetoothState() != BluetoothState.On)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageHintTitle,
|
||||
AppResources.MessageBikesManagementBluetoothActivation,
|
||||
AppResources.MessageAnswerOk);
|
||||
var locksInfo = lockIdList.UpdateById(locksInfoTdo);
|
||||
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
BikeCollection.Update(bikeCollection.UpdateLockInfo(locksInfo), Stations);
|
||||
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Connect to bluetooth devices.
|
||||
ActionText = AppResources.ActivityTextSearchBikes;
|
||||
IEnumerable<LockInfoTdo> locksInfoTdo;
|
||||
try
|
||||
{
|
||||
locksInfoTdo = await LockService.GetLocksStateAsync(
|
||||
lockIdList.Select(x => x.ToLockInfoTdo()).ToList(),
|
||||
LockService.TimeOut.MultiConnect);
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bluetooth state failed. {Exception}", exception);
|
||||
locksInfoTdo = new List<LockInfoTdo>();
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Running command to select bike failed. {Exception}", exception);
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var locksInfo = lockIdList.UpdateById(locksInfoTdo);
|
||||
|
||||
BikeCollection.Update(bikeCollection.UpdateLockInfo(locksInfo), Stations);
|
||||
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.ErrorSelectBikeTitle,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Running command to select bike failed. {Exception}", exception);
|
||||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -254,157 +254,178 @@ namespace TINK.ViewModel
|
|||
public async Task Login()
|
||||
#endif
|
||||
{
|
||||
IsIdle = false;
|
||||
StatusInfoText = AppResources.ActivityTextOneMomentPlease;
|
||||
IAccount account = new EmptyAccount();
|
||||
try
|
||||
if (!IsLoginRequestAllowed)
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Information("User taped login button.");
|
||||
if(TinkApp.ActiveUser.IsLoggedIn)
|
||||
{
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
string.Format(AppResources.ErrorLoginAlreadyLoggedIn,TinkApp.ActiveUser.Mail),
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else if (!m_bMailAndPasswordCandidatesOk)
|
||||
{
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
AppResources.ErrorLoginInvalidMailOrPasswortInput,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsIdle = false;
|
||||
StatusInfoText = AppResources.ActivityTextOneMomentPlease;
|
||||
IAccount account = new EmptyAccount();
|
||||
try
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Information("User taped login button.");
|
||||
|
||||
try
|
||||
{
|
||||
TinkApp.ActiveUser.CheckIsPasswordValid(MailAddress, Password);
|
||||
|
||||
// Do login.
|
||||
account = await TinkApp.GetConnector(CrossConnectivity.Current.IsConnected).Command.DoLogin(MailAddress, Password, TinkApp.ActiveUser.DeviceId);
|
||||
|
||||
await TinkApp.ActiveUser.Login(account);
|
||||
|
||||
// Update map page filter because user might be of both groups TINK an Konrad.
|
||||
TinkApp.GroupFilterMapPage =
|
||||
GroupFilterMapPageHelper.CreateUpdated(
|
||||
TinkApp.GroupFilterMapPage,
|
||||
TinkApp.ActiveUser.DoFilter(TinkApp.FilterGroupSetting.DoFilter()));
|
||||
|
||||
// Update settings page filter because user might be of both groups TINK an Konrad.
|
||||
TinkApp.FilterGroupSetting.DoFilter(TinkApp.ActiveUser.Group);
|
||||
|
||||
// Persist new settings.
|
||||
TinkApp.Save();
|
||||
|
||||
TinkApp.UpdateConnector();
|
||||
}
|
||||
catch (InvalidAuthorizationResponseException l_oException)
|
||||
{
|
||||
// Copri response is invalid.
|
||||
Log.ForContext<LoginPageViewModel>().Error("Login failed (invalid. auth. response). {@l_oException}.", l_oException);
|
||||
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
AppResources.ErrorLoginInvalidAuthorization,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
catch (UnsupportedCopriVersionDetectedException)
|
||||
{
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
string.Format(
|
||||
AppResources.MessageAppVersionIsOutdated,
|
||||
TinkApp.Flavor.GetDisplayName()),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
// Copri server is not reachable.
|
||||
if (l_oException is WebConnectFailureException)
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Information("Login failed (web communication exception). {@l_oException}.", l_oException);
|
||||
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorNoConnectionTitle,
|
||||
AppResources.ErrorNoWeb,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else if (l_oException is UsernamePasswordInvalidException)
|
||||
{
|
||||
// Cookie is empty.
|
||||
Log.ForContext<LoginPageViewModel>().Error("Login failed (empty cookie). {@l_oException}.", l_oException);
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
string.Format(AppResources.ErrorLoginNoCookie, l_oException.Message),
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Error("Login failed. {@l_oException}.", l_oException);
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
l_oException.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Display information that login succeeded.
|
||||
Log.ForContext<LoginPageViewModel>().Information("Login succeeded. {@tinkApp.ActiveUser}.", TinkApp.ActiveUser);
|
||||
|
||||
var title = TinkApp.ActiveUser.Group.Intersect(new List<string> { Model.Connector.FilterHelper.CARGOBIKE, Model.Connector.FilterHelper.CITYBIKE }).Any()
|
||||
? string.Format(AppResources.MessageLoginWelcomeTitleGroup, TinkApp.ActiveUser.GetUserGroupDisplayName())
|
||||
: string.Format(AppResources.MessageLoginWelcomeTitle);
|
||||
|
||||
await m_oViewService.DisplayAlert(
|
||||
title,
|
||||
string.Format(AppResources.MessageLoginWelcome, TinkApp.ActiveUser.Mail),
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
catch (Exception p_oException)
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Error("An unexpected error occurred displaying log out page. {@Exception}", p_oException);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TinkApp.ActiveUser.CheckIsPasswordValid(MailAddress, Password);
|
||||
|
||||
// Do login.
|
||||
account = await TinkApp.GetConnector(CrossConnectivity.Current.IsConnected).Command.DoLogin(MailAddress, Password, TinkApp.ActiveUser.DeviceId);
|
||||
|
||||
await TinkApp.ActiveUser.Login(account);
|
||||
|
||||
// Update map page filter because user might be of both groups TINK an Konrad.
|
||||
TinkApp.GroupFilterMapPage =
|
||||
GroupFilterMapPageHelper.CreateUpdated(
|
||||
TinkApp.GroupFilterMapPage,
|
||||
TinkApp.ActiveUser.DoFilter(TinkApp.FilterGroupSetting.DoFilter()));
|
||||
|
||||
// Update settings page filter because user might be of both groups TINK an Konrad.
|
||||
TinkApp.FilterGroupSetting.DoFilter(TinkApp.ActiveUser.Group);
|
||||
|
||||
// Persist new settings.
|
||||
TinkApp.Save();
|
||||
|
||||
TinkApp.UpdateConnector();
|
||||
}
|
||||
catch (InvalidAuthorizationResponseException l_oException)
|
||||
{
|
||||
// Copri response is invalid.
|
||||
Log.ForContext<LoginPageViewModel>().Error("Login failed (invalid. auth. response). {@l_oException}.", l_oException);
|
||||
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
l_oException.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
catch (UnsupportedCopriVersionDetectedException)
|
||||
{
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
string.Format(
|
||||
AppResources.MessageAppVersionIsOutdated,
|
||||
TinkApp.Flavor.GetDisplayName()),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
// Copri server is not reachable.
|
||||
if (l_oException is WebConnectFailureException)
|
||||
if (!TinkApp.ActiveUser.Group.Contains(Model.Connector.FilterHelper.CARGOBIKE))
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Information("Login failed (web communication exception). {@l_oException}.", l_oException);
|
||||
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorNoConnectionTitle,
|
||||
AppResources.ErrorNoWeb,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else if (l_oException is UsernamePasswordInvalidException)
|
||||
{
|
||||
// Cookie is empty.
|
||||
Log.ForContext<LoginPageViewModel>().Error("Login failed (empty cookie). {@l_oException}.", l_oException);
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
string.Format(AppResources.ErrorLoginNoCookie, l_oException.Message),
|
||||
"OK");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Error("Login failed. {@l_oException}.", l_oException);
|
||||
await m_oViewService.DisplayAlert(
|
||||
AppResources.ErrorLoginTitle,
|
||||
l_oException.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Display information that login succeeded.
|
||||
Log.ForContext<LoginPageViewModel>().Information("Login succeeded. {@tinkApp.ActiveUser}.", TinkApp.ActiveUser);
|
||||
|
||||
var title = TinkApp.ActiveUser.Group.Intersect(new List<string> { Model.Connector.FilterHelper.CARGOBIKE, Model.Connector.FilterHelper.CITYBIKE }).Any()
|
||||
? string.Format(AppResources.MessageLoginWelcomeTitleGroup, TinkApp.ActiveUser.GetUserGroupDisplayName())
|
||||
: string.Format(AppResources.MessageLoginWelcomeTitle);
|
||||
|
||||
await m_oViewService.DisplayAlert(
|
||||
title,
|
||||
string.Format(AppResources.MessageLoginWelcome, TinkApp.ActiveUser.Mail),
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
catch (Exception p_oException)
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Error("An unexpected error occurred displaying log out page. {@Exception}", p_oException);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!TinkApp.ActiveUser.Group.Contains(Model.Connector.FilterHelper.CARGOBIKE))
|
||||
{
|
||||
// No need to show "Anleitung TINK Räder" because user can not use tink.
|
||||
// No need to show "Anleitung TINK Räder" because user can not use tink.
|
||||
#if USEFLYOUT
|
||||
|
||||
m_oViewService.ShowPage(account.IsAgbAcknowledged ? ViewTypes.MapPage : ViewTypes.ManageAccountPage);
|
||||
#else
|
||||
await m_oViewService.ShowPage("//MapPage");
|
||||
#endif
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to map page
|
||||
#if USEFLYOUT
|
||||
m_oViewService.ShowPage(ViewTypes.BikeInfoCarouselPage, AppResources.MarkingLoginInstructions);
|
||||
#else
|
||||
await m_oViewService.ShowPage("//MapPage");
|
||||
#endif
|
||||
}
|
||||
catch (Exception p_oException)
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Error("Ein unerwarteter Fehler ist auf der Seite Anleitung TINK Räder (nach Anmeldeseite) aufgetreten. {@Exception}", p_oException);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to map page
|
||||
#if USEFLYOUT
|
||||
m_oViewService.ShowPage(ViewTypes.BikeInfoCarouselPage, AppResources.MarkingLoginInstructions);
|
||||
#else
|
||||
await m_oViewService.ShowPage("//MapPage");
|
||||
#endif
|
||||
}
|
||||
catch (Exception p_oException)
|
||||
{
|
||||
Log.ForContext<LoginPageViewModel>().Error("Ein unerwarteter Fehler ist auf der Seite Anleitung TINK Räder (nach Anmeldeseite) aufgetreten. {@Exception}", p_oException);
|
||||
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
#if BACKSTYLE
|
||||
// Navigate back to map page.
|
||||
await m_oNavigation.PopToRootAsync();
|
||||
#endif
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
IsIdle = true;
|
||||
StatusInfoText = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Holds whether TINK/ Copri info is shown.</summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue