mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-21 21:46:27 +02:00
3.0.275
This commit is contained in:
parent
f38b516d25
commit
578fcee611
70 changed files with 6828 additions and 9625 deletions
|
@ -301,122 +301,12 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
// Close lock
|
||||
Log.ForContext<ReservedOpen>().Information("User selected disposable bike {bike} in order to manage sound/ alarm settings.", SelectedBike);
|
||||
|
||||
// Check current state.
|
||||
BikesViewModel.ActionText = "Schlosseinstellung abfragen...";
|
||||
bool isAlarmOff;
|
||||
try
|
||||
{
|
||||
isAlarmOff = await LockService[SelectedBike.LockInfo.Id].GetIsAlarmOffAsync();
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Debug("Can not get lock alarm settings. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Abfragen der Alarmeinstellungen!",
|
||||
"Schloss kann erst geschlossen werden, wenn Rad in der Nähe ist.",
|
||||
"OK");
|
||||
|
||||
return this;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Error("Can not get lock alarm settings. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Abfragen der Alarmeinstellungen!",
|
||||
exception.Message,
|
||||
"OK");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
if (isAlarmOff)
|
||||
{
|
||||
// Switch on sound.
|
||||
BikesViewModel.ActionText = "Anschalten von Sounds...";
|
||||
try
|
||||
{
|
||||
await LockService[SelectedBike.LockInfo.Id].SetSoundAsync(SoundSettings.AllOn);
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Debug("Can not turn on sounds. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Anschalten der Sounds!",
|
||||
"Sounds können erst angeschalten werden, wenn Rad in der Nähe ist.",
|
||||
"OK");
|
||||
|
||||
return this;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Error("Can not turn on sounds. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Anschalten der Sounds!",
|
||||
exception.Message,
|
||||
"OK");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Switch off alarm.
|
||||
BikesViewModel.ActionText = "Anschalten von Alarm...";
|
||||
try
|
||||
{
|
||||
await LockService[SelectedBike.LockInfo.Id].SetIsAlarmOffAsync(true);
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Debug("Can not turn on alarm settings. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Anschalten des Alarms!",
|
||||
"Alarm kann erst angeschalten werden, wenn Rad in der Nähe ist.",
|
||||
"OK");
|
||||
|
||||
return this;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext<ReservedOpen>().Error("Can not turn on alarm. {Exception}", exception);
|
||||
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler beim Anschalten des Alarms!",
|
||||
exception.Message,
|
||||
"OK");
|
||||
|
||||
return RequestHandlerFactory.Create(SelectedBike, IsConnectedDelegate, ConnectorFactory, Geolocation, LockService, ViewUpdateManager, SmartDevice, ViewService, BikesViewModel, ActiveUser);
|
||||
}
|
||||
finally
|
||||
{
|
||||
BikesViewModel.ActionText = string.Empty;
|
||||
BikesViewModel.IsIdle = true; // Unlock GUI
|
||||
await ViewUpdateManager().StartUpdateAyncPeridically(); // Restart polling again.
|
||||
}
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
"Hinweis",
|
||||
"Alarm und Sounds erfolgreich aktiviert",
|
||||
"OK");
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// Alarm and sounds are on, toggle to off.
|
||||
// Switch off sound.
|
||||
BikesViewModel.ActionText = "Abschalten der Sounds...";
|
||||
try
|
||||
{
|
||||
await LockService[SelectedBike.LockInfo.Id].SetSoundAsync(SoundSettings.AllOff);
|
||||
await LockService[SelectedBike.LockInfo.Id].SetSoundAsync(SoundSettings.Warn);
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
|
@ -443,11 +333,42 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
return this;
|
||||
}
|
||||
|
||||
// Lower alarm sensivity.
|
||||
BikesViewModel.ActionText = "Setzen Alarm-Einstellungen...";
|
||||
try
|
||||
{
|
||||
await LockService[SelectedBike.LockInfo.Id].SetAlarmSettingsAsync(AlarmSettings.SmallSensivitySilent);
|
||||
}
|
||||
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.",
|
||||
"OK");
|
||||
|
||||
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,
|
||||
"OK");
|
||||
|
||||
return RequestHandlerFactory.Create(SelectedBike, IsConnectedDelegate, ConnectorFactory, Geolocation, LockService, ViewUpdateManager, SmartDevice, ViewService, BikesViewModel, ActiveUser);
|
||||
}
|
||||
|
||||
// Switch off alarm.
|
||||
BikesViewModel.ActionText = "Abschalten von Alarm...";
|
||||
try
|
||||
{
|
||||
await LockService[SelectedBike.LockInfo.Id].SetIsAlarmOffAsync(false);
|
||||
await LockService[SelectedBike.LockInfo.Id].SetIsAlarmOffAsync(true);
|
||||
}
|
||||
catch (OutOfReachException exception)
|
||||
{
|
||||
|
|
|
@ -331,6 +331,7 @@ namespace TINK.ViewModel.Contact
|
|||
var resultStationsAndBikes = await TinkApp.GetConnector(IsConnected).Query.GetBikesAndStationsAsync();
|
||||
|
||||
TinkApp.Stations = resultStationsAndBikes.Response.StationsAll;
|
||||
TinkApp.ResourceUrls = resultStationsAndBikes.GeneralData.ResourceUrls;
|
||||
|
||||
if (Pins.Count > 0 && Pins.Count != resultStationsAndBikes.Response.StationsAll.Count)
|
||||
{
|
||||
|
|
|
@ -1,34 +1,35 @@
|
|||
using System.ComponentModel;
|
||||
using Xamarin.Forms;
|
||||
using TINK.Services.CopriApi.ServerUris;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TINK.ViewModel.Contact
|
||||
{
|
||||
public class HelpContactViewModel : INotifyPropertyChanged
|
||||
public class FeesAndBikesPageViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary> Gets the platfrom specific prefix. </summary>
|
||||
private Func<string, string> ResourceProvider { get; set; }
|
||||
|
||||
/// <summary> Holds value wether site caching is on or off.</summary>
|
||||
bool IsSiteCachingOn { get; }
|
||||
|
||||
private string FeesResourcePath { get; }
|
||||
|
||||
private string BikesResourcePath { get; }
|
||||
|
||||
|
||||
/// <summary> Constructs view model.</summary>
|
||||
/// <param name="isSiteCachingOn">Set of user permissions</param>
|
||||
/// <param name="resourceProvider">Delegate to get an an embedded html ressource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
public HelpContactViewModel(
|
||||
public FeesAndBikesPageViewModel(
|
||||
string hostName,
|
||||
bool isSiteCachingOn,
|
||||
Func<string, string> resourceProvider)
|
||||
string feesResourcePath,
|
||||
string bikesResourcePath,
|
||||
bool isSiteCachingOn)
|
||||
{
|
||||
HostName = hostName;
|
||||
FeesResourcePath = feesResourcePath;
|
||||
BikesResourcePath = bikesResourcePath;
|
||||
IsSiteCachingOn = isSiteCachingOn;
|
||||
|
||||
ResourceProvider = resourceProvider
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(HelpContactViewModel)}-object. No ressource provider availalbe.");
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Holds the name of the host.</summary>
|
||||
|
@ -39,16 +40,16 @@ namespace TINK.ViewModel.Contact
|
|||
{
|
||||
RentBikeText = new HtmlWebViewSource
|
||||
{
|
||||
Html = HostName.GetIsCopri()
|
||||
? ResourceProvider("HtmlResouces.V02.InfoRentBike.html")
|
||||
: await ViewModelHelper.GetSource($"https://{HostName}/{CopriHelper.SHAREE_SILTEFOLDERNAME}/tariff_info_1.html", IsSiteCachingOn)
|
||||
Html = !string.IsNullOrEmpty(FeesResourcePath)
|
||||
? await ViewModelHelper.GetSource($"https://{HostName}/{FeesResourcePath}" /* "site/tariff_info_1.html" */, IsSiteCachingOn)
|
||||
: await Task.FromResult(ViewModelHelper.FromBody("No fees resource available. Resource path is null or empty."))
|
||||
};
|
||||
|
||||
TypesOfBikesText = new HtmlWebViewSource
|
||||
{
|
||||
Html = HostName.GetIsCopri()
|
||||
? ResourceProvider("HtmlResouces.V02.InfoTypesOfBikes.html")
|
||||
: await ViewModelHelper.GetSource($"https://{HostName}/{CopriHelper.SHAREE_SILTEFOLDERNAME}/bike_info.html", IsSiteCachingOn)
|
||||
Html = !string.IsNullOrEmpty(BikesResourcePath)
|
||||
? await ViewModelHelper.GetSource($"https://{HostName}/{BikesResourcePath}" /*"site/bike_info.html"*/, IsSiteCachingOn)
|
||||
: await Task.FromResult(ViewModelHelper.FromBody("No bikes instruction resource available. Resource path is null or empty."))
|
||||
};
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ using Xamarin.Forms;
|
|||
namespace TINK.ViewModel.Info
|
||||
{
|
||||
/// <summary> Manges the tabbed info page. </summary>
|
||||
public class InfoViewModel : INotifyPropertyChanged
|
||||
public class InfoPageViewModel : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary> Fired whenever a property changed.</summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
@ -20,42 +20,56 @@ namespace TINK.ViewModel.Info
|
|||
/// <summary> Holds value wether site caching is on or off.</summary>
|
||||
bool IsSiteCachingOn { get; }
|
||||
|
||||
private string AgbResourcePath { get; }
|
||||
|
||||
private string PrivacyResourcePath { get; }
|
||||
|
||||
private string ImpressResourcePath { get; }
|
||||
|
||||
/// <summary> Constructs Info view model</summary>
|
||||
/// <param name="isSiteCachingOn">Holds value wether site caching is on or off.</param>
|
||||
/// <param name="resourceProvider">Delegate to get an an embedded html ressource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
public InfoViewModel(
|
||||
public InfoPageViewModel(
|
||||
string hostName,
|
||||
bool isSiteCachingOn,
|
||||
string agbResourcePath,
|
||||
string privacyResourcePath,
|
||||
string impressResourcePath,
|
||||
bool isSiteCachingOn,
|
||||
Func<string, string> resourceProvider)
|
||||
{
|
||||
HostName = hostName;
|
||||
|
||||
AgbResourcePath = agbResourcePath;
|
||||
PrivacyResourcePath = privacyResourcePath;
|
||||
ImpressResourcePath = impressResourcePath;
|
||||
IsSiteCachingOn = isSiteCachingOn;
|
||||
|
||||
InfoAgb = new HtmlWebViewSource { Html = "<html>Loading...</html>" };
|
||||
|
||||
ResourceProvider = resourceProvider
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(InfoViewModel)}-object. No ressource provider availalbe.");
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(InfoPageViewModel)}-object. No ressource provider availalbe.");
|
||||
}
|
||||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
public async void OnAppearing()
|
||||
{
|
||||
InfoAgb = await GetAgb(HostName, IsSiteCachingOn, ResourceProvider);
|
||||
|
||||
InfoAgb = await GetAgb(HostName, AgbResourcePath, IsSiteCachingOn);
|
||||
|
||||
InfoPrivacy = new HtmlWebViewSource
|
||||
{
|
||||
Html = await ViewModelHelper.GetSource(
|
||||
$"https://{HostName}/{HostName.GetPrivacyResource()}",
|
||||
IsSiteCachingOn,
|
||||
HostName.GetIsCopri() ? () => ResourceProvider("HtmlResouces.V02.InfoDatenschutz.html") : (Func<string>) null) /* offline resources only available for TINK */,
|
||||
Html = !string.IsNullOrEmpty(PrivacyResourcePath)
|
||||
? await ViewModelHelper.GetSource(
|
||||
$"https://{HostName}/{PrivacyResourcePath}", // "site/privacy.html"
|
||||
IsSiteCachingOn)
|
||||
: await Task.FromResult(ViewModelHelper.FromBody("No privacy resource available. Resource path is null or empty."))
|
||||
};
|
||||
|
||||
InfoImpressum = new HtmlWebViewSource
|
||||
{
|
||||
Html = HostName.GetIsCopri()
|
||||
? ResourceProvider("HtmlResouces.V02.InfoImpressum.html")
|
||||
: await ViewModelHelper.GetSource($"https://{HostName}/{CopriHelper.SHAREE_SILTEFOLDERNAME}/impress.html", IsSiteCachingOn)
|
||||
Html = !string.IsNullOrEmpty(ImpressResourcePath)
|
||||
? await ViewModelHelper.GetSource(
|
||||
$"https://{HostName}/{ImpressResourcePath}", // "site/impress.html"
|
||||
IsSiteCachingOn)
|
||||
: await Task.FromResult(ViewModelHelper.FromBody("No impress resource available. Resource path is null or empty."))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -64,15 +78,16 @@ namespace TINK.ViewModel.Info
|
|||
/// <returns> AGBs</returns>
|
||||
public static async Task<HtmlWebViewSource> GetAgb(
|
||||
string hostName,
|
||||
bool isSiteCachingOn,
|
||||
Func<string, string> resourceProvider)
|
||||
string agbResourcePath,
|
||||
bool isSiteCachingOn)
|
||||
{
|
||||
return new HtmlWebViewSource
|
||||
{
|
||||
Html = await ViewModelHelper.GetSource(
|
||||
$"https://{hostName}/{hostName.GetAGBResource()}",
|
||||
isSiteCachingOn,
|
||||
hostName.GetIsCopri() ? () => resourceProvider("HtmlResouces.V02.InfoAGB.html") : (Func<string>) null) /* offline resources only available for TINK */,
|
||||
Html = !string.IsNullOrEmpty(agbResourcePath)
|
||||
? await ViewModelHelper.GetSource(
|
||||
$"https://{hostName}/{agbResourcePath}", // "agb.html"
|
||||
isSiteCachingOn)
|
||||
: await Task.FromResult(ViewModelHelper.FromBody("No terms resource available. Resource path is null or empty."))
|
||||
};
|
||||
}
|
||||
|
|
@ -325,6 +325,7 @@ namespace TINK.ViewModel.Map
|
|||
var resultStationsAndBikes = await TinkApp.GetConnector(IsConnected).Query.GetBikesAndStationsAsync();
|
||||
|
||||
TinkApp.Stations = resultStationsAndBikes.Response.StationsAll;
|
||||
TinkApp.ResourceUrls = resultStationsAndBikes.GeneralData.ResourceUrls;
|
||||
|
||||
if (!string.IsNullOrEmpty(resultStationsAndBikes?.GeneralData?.MerchantMessage)
|
||||
&& !WasMerchantMessageAlreadyShown)
|
||||
|
|
|
@ -286,8 +286,9 @@ namespace TINK.ViewModel
|
|||
break;
|
||||
}
|
||||
|
||||
return htmlContent ?? string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- ressource.</body>");
|
||||
return htmlContent ?? FromBody("An error occurred loading html- ressource.");
|
||||
}
|
||||
|
||||
public static string FromBody(string message) => $"<!DOCTYPE html><html lang=\"de\"><head><title>Error Information</title></head><body>{message}</body></html>";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace TINK.ViewModel.WhatsNew.Agb
|
|||
/// <summary> Called when page is shown. </summary>
|
||||
public async Task OnAppearing()
|
||||
{
|
||||
InfoAgb = await InfoViewModel.GetAgb(HostName, IsSiteCachingOn, ResourceProvider);
|
||||
InfoAgb = await InfoPageViewModel.GetAgb(HostName, "agbResourcePath", IsSiteCachingOn);
|
||||
}
|
||||
|
||||
/// <summary> User clicks OK button.</summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue