mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-21 21:46:27 +02:00
3.0.267 merged
This commit is contained in:
parent
b6fb6394db
commit
67999ef4ae
171 changed files with 6473 additions and 1093 deletions
|
@ -122,13 +122,13 @@ namespace TINK.Model.Connector
|
|||
Log.ForContext<Command>().Error("Unexpected booking request detected. No user logged in.");
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
public async Task<MiniSurveyModel> DoReturn(
|
||||
public async Task<BookingFinishedModel> DoReturn(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location,
|
||||
ISmartDevice smartDevice)
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected returning request detected. No user logged in.");
|
||||
return await Task.FromResult(new MiniSurveyModel());
|
||||
return await Task.FromResult(new BookingFinishedModel());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -248,7 +248,7 @@ namespace TINK.Model.Connector
|
|||
/// <param name="bike">Bike to return.</param>
|
||||
/// <param name="locaton">Position of the bike.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
public async Task<MiniSurveyModel> DoReturn(
|
||||
public async Task<BookingFinishedModel> DoReturn(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location,
|
||||
ISmartDevice smartDevice)
|
||||
|
@ -258,7 +258,7 @@ namespace TINK.Model.Connector
|
|||
throw new ArgumentNullException("Can not return bike. No bike object available.");
|
||||
}
|
||||
|
||||
ReservationCancelReturnResponse response;
|
||||
DoReturnResponse response;
|
||||
try
|
||||
{
|
||||
response = (await CopriServer.DoReturn(bike.Id, location, smartDevice, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
|
||||
|
@ -270,7 +270,7 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
|
||||
bike.Load(Bikes.Bike.BC.NotifyPropertyChangedLevel.None);
|
||||
return response?.Create() ?? new MiniSurveyModel();
|
||||
return response?.Create() ?? new BookingFinishedModel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace TINK.Model.Connector
|
|||
/// <param name="bike">Bike to return.</param>
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
Task<MiniSurveyModel> DoReturn(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto geolocation = null, ISmartDevice smartDevice = null);
|
||||
Task<BookingFinishedModel> DoReturn(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto geolocation = null, ISmartDevice smartDevice = null);
|
||||
|
||||
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>
|
||||
bool IsConnected { get; }
|
||||
|
|
|
@ -11,26 +11,26 @@ namespace TINK.Model.Connector
|
|||
{
|
||||
/// <summary>Constructs a copri connector object.</summary>
|
||||
/// <param name="activeUri"> Uri to connect to.</param>
|
||||
/// <param name="userAgent">Holds the name and version of the TINKApp.</param>
|
||||
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
|
||||
/// /// <param name="sessionCookie"> Holds the session cookie.</param>
|
||||
/// <param name="p_strMail">Mail of user.</param>
|
||||
/// <param name="expiresAfter">Timespan which holds value after which cache expires.</param>
|
||||
/// <param name="server"> Provides cached addess to copri.</param>
|
||||
public Connector(
|
||||
Uri activeUri,
|
||||
string userAgent,
|
||||
AppContextInfo appContextInfo,
|
||||
string sessionCookie,
|
||||
string mail,
|
||||
TimeSpan? expiresAfter = null,
|
||||
ICachedCopriServer server = null )
|
||||
{
|
||||
Command = GetCommand(
|
||||
server ?? new CopriProviderHttps(activeUri, TinkApp.MerchantId, userAgent, sessionCookie),
|
||||
server ?? new CopriProviderHttps(activeUri, TinkApp.MerchantId, appContextInfo, sessionCookie),
|
||||
sessionCookie,
|
||||
mail);
|
||||
|
||||
Query = GetQuery(
|
||||
server ?? new CopriProviderHttps(activeUri, TinkApp.MerchantId, userAgent, sessionCookie, expiresAfter),
|
||||
server ?? new CopriProviderHttps(activeUri, TinkApp.MerchantId, appContextInfo, sessionCookie, expiresAfter),
|
||||
sessionCookie,
|
||||
mail);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -7,12 +8,19 @@ namespace TINK.Model.Connector
|
|||
/// <summary>
|
||||
/// Gets a connector object depending on whether beein onlin or offline.
|
||||
/// </summary>
|
||||
/// <param name="isConnected">True if online, false if offline</param>
|
||||
/// <param name="isConnected">True if online, false if offline. If offline cache connector is returned.</param>
|
||||
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
|
||||
/// <returns></returns>
|
||||
public static IConnector Create(bool isConnected, Uri activeUri, string userAgent, string sessionCookie, string mail, TimeSpan? expiresAfter = null)
|
||||
public static IConnector Create(
|
||||
bool isConnected,
|
||||
Uri activeUri,
|
||||
AppContextInfo appContextInfo,
|
||||
string sessionCookie,
|
||||
string mail,
|
||||
TimeSpan? expiresAfter = null)
|
||||
{
|
||||
return isConnected
|
||||
? new Connector(activeUri, userAgent, sessionCookie, mail, expiresAfter: expiresAfter) as IConnector
|
||||
? new Connector(activeUri, appContextInfo, sessionCookie, mail, expiresAfter: expiresAfter) as IConnector
|
||||
: new ConnectorCache(sessionCookie, mail);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
/// Was "Konrad" up to version 3.0.258.
|
||||
/// Specified first: "KN300001" (RG).
|
||||
/// </remarks>
|
||||
public const string FILTERKONRAD = "300101";
|
||||
public const string CITYBIKE = "300103";
|
||||
|
||||
/// <summary> Holds the tink group (Lastenräder).</summary>
|
||||
/// <remarks>
|
||||
/// Was "TINK" up to version 3.0.258.
|
||||
/// Specified first: "KN300029" (RG).
|
||||
/// </remarks>
|
||||
public const string FILTERTINKGENERAL = "300103";
|
||||
public const string CARGOBIKE = "300101";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,8 @@ namespace TINK.Model.Connector
|
|||
var result = await m_oInnerQuery.GetBikesAsync();
|
||||
return new Result<BikeCollection>(
|
||||
result.Source,
|
||||
new BikeCollection(DoFilter(result.Response, Filter)),
|
||||
new BikeCollection(DoFilter(result.Response, Filter)),
|
||||
result.GeneralData,
|
||||
result.Exception);
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,8 @@ namespace TINK.Model.Connector
|
|||
var result = await m_oInnerQuery.GetBikesOccupiedAsync();
|
||||
return new Result<BikeCollection>(
|
||||
result.Source,
|
||||
new BikeCollection(result.Response.ToDictionary(x => x.Id)),
|
||||
new BikeCollection(result.Response.ToDictionary(x => x.Id)),
|
||||
result.GeneralData,
|
||||
result.Exception);
|
||||
}
|
||||
|
||||
|
@ -95,7 +97,8 @@ namespace TINK.Model.Connector
|
|||
var filteredBikesAndStations = new Result<StationsAndBikesContainer>(
|
||||
providerBikesAndStations.Source,
|
||||
new StationsAndBikesContainer(filteredStationsDictionary, filteredBikesDictionary),
|
||||
providerBikesAndStations.Exception); ;
|
||||
providerBikesAndStations.GeneralData,
|
||||
providerBikesAndStations.Exception);
|
||||
|
||||
return filteredBikesAndStations;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace TINK.Model.Connector
|
|||
return new Result<BikeCollection>(
|
||||
result.Source,
|
||||
new BikeCollection(result.Response.ToDictionary(x => x.Id)),
|
||||
result.GeneralData,
|
||||
result.Exception);
|
||||
}
|
||||
|
||||
|
@ -72,6 +73,7 @@ namespace TINK.Model.Connector
|
|||
return new Result<BikeCollection>(
|
||||
result.Source,
|
||||
new BikeCollection(result.Response.ToDictionary(x => x.Id)),
|
||||
result.GeneralData,
|
||||
result.Exception);
|
||||
}
|
||||
|
||||
|
@ -86,6 +88,7 @@ namespace TINK.Model.Connector
|
|||
new StationsAndBikesContainer(
|
||||
new StationDictionary(result.Response.StationsAll.CopriVersion, result.Response.StationsAll.ToDictionary(x => x.Id)),
|
||||
new BikeCollection(result.Response.Bikes.ToDictionary(x => x.Id))),
|
||||
result.GeneralData,
|
||||
result.Exception);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||
using TINK.Model.Bike;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.Services.CopriApi;
|
||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
|
@ -39,6 +40,7 @@ namespace TINK.Model.Connector
|
|||
new StationsAndBikesContainer(
|
||||
resultStations.Response.GetStationsAllMutable(),
|
||||
(await server.GetBikesAvailable(true)).Response.GetBikesAvailable()),
|
||||
resultStations.GeneralData,
|
||||
resultStations.Exception);
|
||||
}
|
||||
|
||||
|
@ -51,6 +53,7 @@ namespace TINK.Model.Connector
|
|||
new StationsAndBikesContainer(
|
||||
(await server.GetStations(true)).Response.GetStationsAllMutable(),
|
||||
resultBikes.Response.GetBikesAvailable()),
|
||||
resultBikes.GeneralData,
|
||||
resultBikes.Exception);
|
||||
}
|
||||
|
||||
|
@ -60,7 +63,8 @@ namespace TINK.Model.Connector
|
|||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
resultStations.Source,
|
||||
new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable()));
|
||||
new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable()),
|
||||
resultStations.GeneralData);
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes occupied. </summary>
|
||||
|
@ -71,7 +75,8 @@ namespace TINK.Model.Connector
|
|||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
await Task.Run(() => new BikeCollection(new Dictionary<string, BikeInfo>())),
|
||||
new System.Exception("Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet."));
|
||||
new GeneralData(),
|
||||
new Exception("Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet."));
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes available. </summary>
|
||||
|
@ -80,7 +85,7 @@ namespace TINK.Model.Connector
|
|||
{
|
||||
var result = await server.GetBikesAvailable();
|
||||
server.AddToCache(result);
|
||||
return new Result<BikeCollection>(result.Source, result.Response.GetBikesAvailable(), result.Exception);
|
||||
return new Result<BikeCollection>(result.Source, result.Response.GetBikesAvailable(), result.GeneralData, result.Exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace TINK.Model.Connector
|
|||
(await server.GetBikesOccupied(true)).Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
stationsResponse.GeneralData,
|
||||
stationsResponse.Exception);
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,7 @@ namespace TINK.Model.Connector
|
|||
(await server.GetBikesOccupied(true)).Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
bikesAvailableResponse.GeneralData,
|
||||
bikesAvailableResponse.Exception);
|
||||
}
|
||||
|
||||
|
@ -78,6 +80,7 @@ namespace TINK.Model.Connector
|
|||
bikesOccupiedResponse.Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
bikesOccupiedResponse.GeneralData,
|
||||
bikesOccupiedResponse.Exception);
|
||||
}
|
||||
|
||||
|
@ -98,6 +101,7 @@ namespace TINK.Model.Connector
|
|||
return new Result<StationsAndBikesContainer>(
|
||||
stationsResponse.Source,
|
||||
new StationsAndBikesContainer(stationsMutable, bikesMutable),
|
||||
stationsResponse.GeneralData,
|
||||
exceptions.Length > 0 ? new AggregateException(exceptions) : null);
|
||||
}
|
||||
|
||||
|
@ -107,7 +111,7 @@ namespace TINK.Model.Connector
|
|||
{
|
||||
var result = await server.GetBikesOccupied();
|
||||
server.AddToCache(result);
|
||||
return new Result<BikeCollection>(result.Source, result.Response.GetBikesOccupied(Mail, DateTimeProvider), result.Exception);
|
||||
return new Result<BikeCollection>(result.Source, result.Response.GetBikesOccupied(Mail, DateTimeProvider), result.GeneralData, result.Exception);
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes available and bikes occupied. </summary>
|
||||
|
@ -127,6 +131,7 @@ namespace TINK.Model.Connector
|
|||
(await server.GetBikesOccupied(true)).Response,
|
||||
Mail,
|
||||
DateTimeProvider),
|
||||
l_oBikesAvailableResponse.GeneralData,
|
||||
l_oBikesAvailableResponse.Exception);
|
||||
}
|
||||
|
||||
|
@ -142,6 +147,7 @@ namespace TINK.Model.Connector
|
|||
l_oBikesOccupiedResponse.Response,
|
||||
Mail,
|
||||
DateTimeProvider),
|
||||
l_oBikesOccupiedResponse.GeneralData,
|
||||
l_oBikesOccupiedResponse.Exception);
|
||||
|
||||
}
|
||||
|
@ -153,6 +159,7 @@ namespace TINK.Model.Connector
|
|||
return new Result<BikeCollection>(
|
||||
l_oBikesAvailableResponse.Source,
|
||||
UpdaterJSON.GetBikesAll(l_oBikesAvailableResponse.Response, l_oBikesOccupiedResponse.Response, Mail, DateTimeProvider),
|
||||
l_oBikesAvailableResponse.GeneralData,
|
||||
l_oBikesAvailableResponse.Exception != null || l_oBikesOccupiedResponse.Exception != null ? new AggregateException(new[] { l_oBikesAvailableResponse.Exception, l_oBikesOccupiedResponse.Exception }) : null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||
using TINK.Model.Bike;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.Services.CopriApi;
|
||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
|
@ -34,7 +35,8 @@ namespace TINK.Model.Connector
|
|||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
new StationsAndBikesContainer( stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable()));
|
||||
new StationsAndBikesContainer(stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable()),
|
||||
stationsAllResponse.GetGeneralData());
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes occupied. </summary>
|
||||
|
@ -45,16 +47,19 @@ namespace TINK.Model.Connector
|
|||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
await Task.Run(() => new BikeCollection(new Dictionary<string, BikeInfo>())),
|
||||
new System.Exception("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet."));
|
||||
new GeneralData(),
|
||||
new Exception("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet."));
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes occupied. </summary>
|
||||
/// <returns> Collection of bikes. </returns>
|
||||
public async Task<Result<BikeCollection>> GetBikesAsync()
|
||||
{
|
||||
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
|
||||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
(await server.GetBikesAvailableAsync()).GetBikesAvailable());
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
bikesAvailableResponse.GetBikesAvailable(),
|
||||
bikesAvailableResponse.GetGeneralData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,27 +39,31 @@ namespace TINK.Model.Connector
|
|||
typeof(CopriCallsMonkeyStore),
|
||||
new StationsAndBikesContainer(
|
||||
stationResponse.GetStationsAllMutable(),
|
||||
UpdaterJSON.GetBikesAll(bikesAvailableResponse, bikesOccupiedResponse, Mail, DateTimeProvider)));
|
||||
UpdaterJSON.GetBikesAll(bikesAvailableResponse, bikesOccupiedResponse, Mail, DateTimeProvider)),
|
||||
stationResponse.GetGeneralData());
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes occupied. </summary>
|
||||
/// <returns>Collection of bikes.</returns>
|
||||
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
|
||||
{
|
||||
var bikesOccupiedResponse = (await server.GetBikesOccupiedAsync());
|
||||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
(await server.GetBikesOccupiedAsync()).GetBikesOccupied(Mail, DateTimeProvider));
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
bikesOccupiedResponse.GetBikesOccupied(Mail, DateTimeProvider),
|
||||
bikesOccupiedResponse.GetGeneralData());
|
||||
}
|
||||
/// <summary> Gets bikes available and bikes occupied. </summary>
|
||||
/// <returns>Collection of bikes.</returns>
|
||||
public async Task<Result<BikeCollection>> GetBikesAsync()
|
||||
{
|
||||
var l_oBikesAvailableResponse = await server.GetBikesAvailableAsync();
|
||||
var l_oBikesOccupiedResponse = await server.GetBikesOccupiedAsync();
|
||||
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
|
||||
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
|
||||
|
||||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
UpdaterJSON.GetBikesAll(l_oBikesAvailableResponse, l_oBikesOccupiedResponse, Mail, DateTimeProvider));
|
||||
UpdaterJSON.GetBikesAll(bikesAvailableResponse, bikesOccupiedResponse, Mail, DateTimeProvider),
|
||||
bikesAvailableResponse.GetGeneralData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ using TINK.Model.Station.Operator;
|
|||
using Xamarin.Forms;
|
||||
using System.Linq;
|
||||
using TINK.Model.MiniSurvey;
|
||||
using TINK.Services.CopriApi;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -78,6 +79,14 @@ namespace TINK.Model.Connector
|
|||
return stations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets general data from COPRI response.
|
||||
/// </summary>
|
||||
/// <param name="response">Response to get data from.</param>
|
||||
/// <returns>General data object initialized form COPRI response.</returns>
|
||||
public static GeneralData GetGeneralData(this ResponseBase response)
|
||||
=> new GeneralData(response.merchant_message, response.GetCopriVersion());
|
||||
|
||||
/// <summary> Gets account object from login response.</summary>
|
||||
/// <param name="merchantId">Needed to extract cookie from autorization response.</param>
|
||||
/// <param name="loginResponse">Response to get session cookie and debug level from.</param>
|
||||
|
@ -512,22 +521,28 @@ namespace TINK.Model.Connector
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary> Creates a survey object from response.</summary>
|
||||
/// <summary> Creates a booking finished object from response.</summary>
|
||||
/// <param name="response">Response to create survey object from.</param>
|
||||
public static MiniSurveyModel Create(this ReservationCancelReturnResponse response)
|
||||
public static BookingFinishedModel Create(this DoReturnResponse response)
|
||||
{
|
||||
if (response?.user_miniquery == null)
|
||||
var bookingFinished = new BookingFinishedModel
|
||||
{
|
||||
return new MiniSurveyModel();
|
||||
Co2Saving = response?.co2saving
|
||||
};
|
||||
|
||||
if (response?.user_miniquery == null)
|
||||
|
||||
{
|
||||
return bookingFinished;
|
||||
}
|
||||
|
||||
var miniquery = response.user_miniquery;
|
||||
var survey = new MiniSurveyModel
|
||||
{
|
||||
Title = miniquery.title,
|
||||
Subtitle = miniquery.subtitle,
|
||||
Footer = miniquery.footer
|
||||
};
|
||||
bookingFinished.MiniSurvey = new MiniSurveyModel
|
||||
{
|
||||
Title = miniquery.title,
|
||||
Subtitle = miniquery.subtitle,
|
||||
Footer = miniquery.footer
|
||||
};
|
||||
|
||||
foreach (var question in miniquery?.questions?.OrderBy(x => x.Key) ?? new Dictionary<string, MiniSurveyResponse.Question>().OrderBy(x => x.Key))
|
||||
{
|
||||
|
@ -538,12 +553,12 @@ namespace TINK.Model.Connector
|
|||
continue;
|
||||
}
|
||||
|
||||
survey.Questions.Add(
|
||||
bookingFinished.MiniSurvey.Questions.Add(
|
||||
question.Key,
|
||||
new MiniSurveyModel.QuestionModel());
|
||||
}
|
||||
|
||||
return survey;
|
||||
return bookingFinished;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ namespace TINK.Model
|
|||
get
|
||||
{
|
||||
return new GroupFilterSettings(new Dictionary<string, FilterState> {
|
||||
{ FilterHelper.FILTERTINKGENERAL, FilterState.On },
|
||||
{FilterHelper.FILTERKONRAD, FilterState.On }
|
||||
{ FilterHelper.CARGOBIKE, FilterState.On },
|
||||
{FilterHelper.CITYBIKE, FilterState.On }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ namespace TINK.Model
|
|||
get
|
||||
{
|
||||
return new GroupFilterMapPage(new Dictionary<string, FilterState> {
|
||||
{ FilterHelper.FILTERTINKGENERAL, FilterState.On },
|
||||
{FilterHelper.FILTERKONRAD, FilterState.Off }
|
||||
{ FilterHelper.CARGOBIKE, FilterState.On },
|
||||
{FilterHelper.CITYBIKE, FilterState.Off }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
namespace TINK.Model.MiniSurvey
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds mini survey.
|
||||
/// </summary>
|
||||
public class MiniSurveyModel
|
||||
{
|
||||
public enum Type
|
||||
|
@ -12,21 +15,17 @@ namespace TINK.Model.MiniSurvey
|
|||
}
|
||||
public class QuestionModel
|
||||
{
|
||||
public QuestionModel()
|
||||
{
|
||||
PossibleAnswers = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the query description.
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
public Type Type { get; set; }
|
||||
|
||||
public Dictionary<string, string> PossibleAnswers { get; private set; }
|
||||
}
|
||||
|
||||
public MiniSurveyModel()
|
||||
{
|
||||
Questions = new Dictionary<string, QuestionModel>();
|
||||
/// <summary>
|
||||
/// Holds the collection of possible answers.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> PossibleAnswers { get; private set; } = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public string Title { get; set; }
|
||||
|
@ -35,6 +34,6 @@ namespace TINK.Model.MiniSurvey
|
|||
|
||||
public string Footer { get; set; }
|
||||
|
||||
public Dictionary<string, QuestionModel> Questions { get; }
|
||||
public Dictionary<string, QuestionModel> Questions { get; } = new Dictionary<string, QuestionModel>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,16 +215,8 @@ namespace TINK.Model
|
|||
GeolocationServices = geolocationServicesContainer
|
||||
?? throw new ArgumentException($"Can not instantiate {nameof(TinkApp)}- object. No geolocation services container object available.");
|
||||
|
||||
if (settings.ActiveUri == new Uri(CopriServerUriList.TINK_LIVE) ||
|
||||
settings.ActiveUri == new Uri(CopriServerUriList.TINK_DEVEL))
|
||||
{
|
||||
FilterGroupSetting = settings.GroupFilterSettings;
|
||||
GroupFilterMapPage = settings.GroupFilterMapPage;
|
||||
} else
|
||||
{
|
||||
FilterGroupSetting = new GroupFilterSettings();
|
||||
GroupFilterMapPage = new GroupFilterMapPage();
|
||||
}
|
||||
FilterGroupSetting = settings.GroupFilterSettings;
|
||||
GroupFilterMapPage = settings.GroupFilterMapPage;
|
||||
|
||||
CenterMapToCurrentLocation = settings.CenterMapToCurrentLocation;
|
||||
|
||||
|
|
|
@ -455,9 +455,29 @@ namespace TINK.Model
|
|||
AppResources.ChangeLog3_0_250 // Third-party components updated.
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 257),
|
||||
new Version(3, 0, 260),
|
||||
// Same info as for version 3.0.251 and 3.0.252
|
||||
AppResources.ChangeLog3_0_231 // Minor improvements.
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 263),
|
||||
AppResources.ChangeLog3_0_263
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 264),
|
||||
AppResources.ChangeLog3_0_264
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 265),
|
||||
AppResources.ChangeLog3_0_265
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 266),
|
||||
AppResources.ChangeLog3_0_266
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 267),
|
||||
AppResources.ChangeLog3_0_231 // Minor improvements.
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -871,6 +871,44 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to CO2 saving is displayed for bikes with GPS-lock after returning bike..
|
||||
/// </summary>
|
||||
public static string ChangeLog3_0_263 {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangeLog3_0_263", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bug "object reference not set ...." <a href="https://dev.azure.com/TeilRad/sharee.bike%20App/_workitems/edit/186">185</a> fixed..
|
||||
/// </summary>
|
||||
public static string ChangeLog3_0_264 {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangeLog3_0_264", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Filter functionality city bike/ cargo bike improved.
|
||||
///Layouting improved.
|
||||
///App supports deep linking..
|
||||
/// </summary>
|
||||
public static string ChangeLog3_0_265 {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangeLog3_0_265", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Location permissions handling improved..
|
||||
/// </summary>
|
||||
public static string ChangeLog3_0_266 {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangeLog3_0_266", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Lock of rented bike can not be found..
|
||||
/// </summary>
|
||||
|
@ -1221,6 +1259,24 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cargo bike.
|
||||
/// </summary>
|
||||
public static string MarkingCargoBike {
|
||||
get {
|
||||
return ResourceManager.GetString("MarkingCargoBike", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to City bike.
|
||||
/// </summary>
|
||||
public static string MarkingCityBike {
|
||||
get {
|
||||
return ResourceManager.GetString("MarkingCityBike", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Please open a bike station page to to contact the bike sharing operator..
|
||||
/// </summary>
|
||||
|
|
|
@ -710,4 +710,24 @@ Kleinere Verbesserungen.</value>
|
|||
Kartenzentrierfehler behoben.
|
||||
Kleine Verbesserungen.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_263" xml:space="preserve">
|
||||
<value>Bei Fahrrädern mit GPS-Schloss wird die CO2-Einsparung nach der Rückgabe des Fahrrads angezeigt.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_264" xml:space="preserve">
|
||||
<value>Fehler "object reference not set ...." <a href="https://dev.azure.com/TeilRad/sharee.bike%20App/_workitems/edit/186">185</a> behoben.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_265" xml:space="preserve">
|
||||
<value>Filterfunktion Stadtrad/ Lastenrad verbessert.
|
||||
Layouting verbessert.
|
||||
Deep linking wird unterstützt.</value>
|
||||
</data>
|
||||
<data name="MarkingCargoBike" xml:space="preserve">
|
||||
<value>Lastenrad</value>
|
||||
</data>
|
||||
<data name="MarkingCityBike" xml:space="preserve">
|
||||
<value>Stadtrad</value>
|
||||
</data>
|
||||
<data name="MessageBikesManagementTariffDescriptionTariffHeaderNameId" xml:space="preserve">
|
||||
<value>Tarif {0}, Nr. {1}</value>
|
||||
</data>
|
||||
</root>
|
|
@ -805,4 +805,27 @@ Minor fixes.</value>
|
|||
Center map to current position issue fixed.
|
||||
Minor improvements.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_263" xml:space="preserve">
|
||||
<value>CO2 saving is displayed for bikes with GPS-lock after returning bike.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_264" xml:space="preserve">
|
||||
<value>Bug "object reference not set ...." <a href="https://dev.azure.com/TeilRad/sharee.bike%20App/_workitems/edit/186">185</a> fixed.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_265" xml:space="preserve">
|
||||
<value>Filter functionality city bike/ cargo bike improved.
|
||||
Layouting improved.
|
||||
App supports deep linking.</value>
|
||||
</data>
|
||||
<data name="MarkingCargoBike" xml:space="preserve">
|
||||
<value>Cargo bike</value>
|
||||
</data>
|
||||
<data name="MarkingCityBike" xml:space="preserve">
|
||||
<value>City bike</value>
|
||||
</data>
|
||||
<data name="MessageBikesManagementTariffDescriptionTariffHeaderNameId" xml:space="preserve">
|
||||
<value>Tariff {0}, nr. {1}</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_266" xml:space="preserve">
|
||||
<value>Location permissions handling improved.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -952,6 +952,34 @@ Minor improvements.</source>
|
|||
Kartenzentrierfehler behoben.
|
||||
Kleine Verbesserungen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog3_0_263" translate="yes" xml:space="preserve">
|
||||
<source>CO2 saving is displayed for bikes with GPS-lock after returning bike.</source>
|
||||
<target state="translated">Bei Fahrrädern mit GPS-Schloss wird die CO2-Einsparung nach der Rückgabe des Fahrrads angezeigt.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog3_0_264" translate="yes" xml:space="preserve">
|
||||
<source>Bug "object reference not set ...." <bpt id="1"><a href="https://dev.azure.com/TeilRad/sharee.bike%20App/_workitems/edit/186"></bpt>185<ept id="1"></a></ept> fixed.</source>
|
||||
<target state="translated">Fehler "object reference not set ...." <bpt id="1"><a href="https://dev.azure.com/TeilRad/sharee.bike%20App/_workitems/edit/186"></bpt>185<ept id="1"></a></ept> behoben.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog3_0_265" translate="yes" xml:space="preserve">
|
||||
<source>Filter functionality city bike/ cargo bike improved.
|
||||
Layouting improved.
|
||||
App supports deep linking.</source>
|
||||
<target state="translated">Filterfunktion Stadtrad/ Lastenrad verbessert.
|
||||
Layouting verbessert.
|
||||
Deep linking wird unterstützt.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingCargoBike" translate="yes" xml:space="preserve">
|
||||
<source>Cargo bike</source>
|
||||
<target state="translated">Lastenrad</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingCityBike" translate="yes" xml:space="preserve">
|
||||
<source>City bike</source>
|
||||
<target state="translated">Stadtrad</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MessageBikesManagementTariffDescriptionTariffHeaderNameId" translate="yes" xml:space="preserve">
|
||||
<source>Tariff {0}, nr. {1}</source>
|
||||
<target state="translated">Tarif {0}, Nr. {1}</target>
|
||||
</trans-unit>
|
||||
</group>
|
||||
</body>
|
||||
</file>
|
||||
|
|
35
TINKLib/Repository/AppContextInfo.cs
Normal file
35
TINKLib/Repository/AppContextInfo.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
|
||||
namespace TINK.Repository
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds info passed to COPRI.
|
||||
/// </summary>
|
||||
public class AppContextInfo
|
||||
{
|
||||
public AppContextInfo(string merchantId, string name, Version version)
|
||||
{
|
||||
Name = !string.IsNullOrEmpty(name)
|
||||
? name
|
||||
: throw new ArgumentNullException(nameof(name));
|
||||
|
||||
Version = version;
|
||||
|
||||
MerchantId = !string.IsNullOrEmpty(merchantId)
|
||||
? merchantId
|
||||
: throw new ArgumentNullException(nameof(merchantId));
|
||||
}
|
||||
|
||||
/// <summary> Name of the app. </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <summary> Version of the app.</summary>
|
||||
public Version Version { get; private set; }
|
||||
|
||||
/// <summary> Merchang id of the app. </summary>
|
||||
public string MerchantId { get; private set; }
|
||||
|
||||
/// <summary> Returns http- user agent.</summary>
|
||||
public string UserAgent { get => $"{Name}/{Version}"; }
|
||||
}
|
||||
}
|
|
@ -22,25 +22,23 @@ namespace TINK.Repository
|
|||
|
||||
/// <summary> Initializes a instance of the copri calls https object. </summary>
|
||||
/// <param name="copriHost">Host to connect to. </param>
|
||||
/// <param name="merchantId">Id of the merchant.</param>
|
||||
/// <param name="userAgent">Holds the name and version of the TINKApp.</param>
|
||||
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
|
||||
/// <param name="sessionCookie">Session cookie if user is logged in, null otherwise.</param>
|
||||
public CopriCallsHttps(
|
||||
Uri copriHost,
|
||||
string merchantId,
|
||||
string userAgent,
|
||||
AppContextInfo appContextInfo,
|
||||
string sessionCookie = null)
|
||||
{
|
||||
m_oCopriHost = copriHost
|
||||
?? throw new System.Exception($"Can not construct {GetType().ToString()}- object. Uri of copri host must not be null.");
|
||||
?? throw new System.Exception($"Can not construct {GetType()}- object. Uri of copri host must not be null.");
|
||||
|
||||
UserAgent = !string.IsNullOrEmpty(userAgent)
|
||||
? userAgent
|
||||
: throw new System.Exception($"Can not construct {GetType().ToString()}- object. User agent must not be null or empty.");
|
||||
UserAgent = appContextInfo != null
|
||||
? appContextInfo.UserAgent
|
||||
: throw new System.Exception($"Can not construct {GetType()}- object. User agent must not be null or empty.");
|
||||
|
||||
requestBuilder = string.IsNullOrEmpty(sessionCookie)
|
||||
? new RequestBuilder(merchantId) as IRequestBuilder
|
||||
: new RequestBuilderLoggedIn(merchantId, sessionCookie);
|
||||
? new RequestBuilder(appContextInfo.MerchantId) as IRequestBuilder
|
||||
: new RequestBuilderLoggedIn(appContextInfo.MerchantId, sessionCookie);
|
||||
}
|
||||
|
||||
/// <summary> Holds the URL for rest calls.</summary>
|
||||
|
@ -621,10 +619,10 @@ namespace TINK.Repository
|
|||
string userAgent = null)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
string cancelOrReturnResponse;
|
||||
string doReturnResponse;
|
||||
try
|
||||
{
|
||||
cancelOrReturnResponse = await PostAsync(copriHost, command, userAgent);
|
||||
doReturnResponse = await PostAsync(copriHost, command, userAgent);
|
||||
}
|
||||
catch (System.Exception l_oException)
|
||||
{
|
||||
|
@ -642,7 +640,7 @@ namespace TINK.Repository
|
|||
}
|
||||
|
||||
// Extract bikes from response.
|
||||
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(cancelOrReturnResponse)?.shareejson;
|
||||
return JsonConvertRethrow.DeserializeObject<ResponseContainer<DoReturnResponse>>(doReturnResponse)?.shareejson;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace TINK.Repository.Response
|
||||
{
|
||||
|
|
|
@ -17,6 +17,10 @@ namespace TINK.Repository.Response
|
|||
[DataMember]
|
||||
public string authcookie { get; private set; }
|
||||
|
||||
/// <summary> Message shown to user.</summary>
|
||||
[DataMember]
|
||||
public string merchant_message { get; private set; }
|
||||
|
||||
/// <summary> Textual description of response. </summary>
|
||||
public new string ToString()
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Request;
|
||||
|
@ -29,22 +30,21 @@ namespace TINK.Model.Services.CopriApi
|
|||
|
||||
/// <summary> Constructs copri provider object to connet to https using a cache objet. </summary>
|
||||
/// <param name="copriHost"></param>
|
||||
/// <param name="merchantId"></param>
|
||||
/// <param name="userAgent">Holds the name and version of the TINKApp.</param>
|
||||
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
|
||||
/// <param name="sessionCookie">Cookie of user if a user is logged in, false otherwise.</param>
|
||||
/// <param name="expiresAfter">Timespan which holds value after which cache expires.</param>
|
||||
/// <param name="isExpired">Delegate which returns if cache conted is out of date or not.</param>
|
||||
public CopriProviderHttps(
|
||||
Uri copriHost,
|
||||
string merchantId,
|
||||
string userAgent,
|
||||
AppContextInfo appContextInfo,
|
||||
string sessionCookie = null,
|
||||
TimeSpan? expiresAfter = null,
|
||||
ICopriCache cacheServer = null,
|
||||
ICopriServer httpsServer = null)
|
||||
{
|
||||
CacheServer = cacheServer ?? new CopriCallsMonkeyStore(merchantId, sessionCookie, expiresAfter);
|
||||
HttpsServer = httpsServer ?? new CopriCallsHttps(copriHost, merchantId, userAgent, sessionCookie);
|
||||
HttpsServer = httpsServer ?? new CopriCallsHttps(copriHost, appContextInfo, sessionCookie);
|
||||
}
|
||||
|
||||
/// <summary>Gets bikes available.</summary>
|
||||
|
@ -59,22 +59,26 @@ namespace TINK.Model.Services.CopriApi
|
|||
{
|
||||
// No need to query because previous answer is not yet outdated.
|
||||
Log.ForContext<CopriProviderHttps>().Debug($"Returning bikes available from cache.");
|
||||
return new Result<BikesAvailableResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetBikesAvailableAsync());
|
||||
var bikesAvailableResponse = await CacheServer.GetBikesAvailableAsync();
|
||||
return new Result<BikesAvailableResponse>(typeof(CopriCallsMonkeyStore), bikesAvailableResponse, bikesAvailableResponse.GetGeneralData());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<CopriProviderHttps>().Debug($"Querrying bikes available from copri.");
|
||||
var bikesAvailableResponse = await HttpsServer.GetBikesAvailableAsync();
|
||||
return new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
(await HttpsServer.GetBikesAvailableAsync()).GetIsResponseOk("Abfrage der verfügbaren Räder fehlgeschlagen."));
|
||||
bikesAvailableResponse.GetIsResponseOk("Abfrage der verfügbaren Räder fehlgeschlagen."),
|
||||
bikesAvailableResponse.GetGeneralData());
|
||||
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Return response from cache.
|
||||
Log.ForContext<CopriProviderHttps>().Debug("An error occurred querrying bikes available. {Exception}.", exception);
|
||||
return new Result<BikesAvailableResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetBikesAvailableAsync(), exception);
|
||||
var bikesAvailableResponse = await CacheServer.GetBikesAvailableAsync();
|
||||
return new Result<BikesAvailableResponse>(typeof(CopriCallsMonkeyStore), bikesAvailableResponse, bikesAvailableResponse.GetGeneralData(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,23 +92,27 @@ namespace TINK.Model.Services.CopriApi
|
|||
|| fromCache)
|
||||
{
|
||||
// No need to query because previous answer is not yet outdated.
|
||||
var bikesOccupiedResponse = await CacheServer.GetBikesOccupiedAsync();
|
||||
Log.ForContext<CopriProviderHttps>().Debug($"Returning bikes occupied from cache.");
|
||||
return new Result<BikesReservedOccupiedResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetBikesOccupiedAsync());
|
||||
return new Result<BikesReservedOccupiedResponse>(typeof(CopriCallsMonkeyStore), bikesOccupiedResponse, bikesOccupiedResponse.GetGeneralData());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Log.ForContext<CopriProviderHttps>().Debug($"Querrying bikes occupied from copri.");
|
||||
var bikesOccupiedResponse = await HttpsServer.GetBikesOccupiedAsync();
|
||||
return new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
(await HttpsServer.GetBikesOccupiedAsync()).GetIsResponseOk("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen."));
|
||||
bikesOccupiedResponse.GetIsResponseOk("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen."),
|
||||
bikesOccupiedResponse.GetGeneralData());
|
||||
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Return response from cache.
|
||||
Log.ForContext<CopriProviderHttps>().Debug("An error occurred querrying bikes occupied. {Exception}.", exception);
|
||||
return new Result<BikesReservedOccupiedResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetBikesOccupiedAsync(), exception);
|
||||
var bikesOccupiedResponse = await CacheServer.GetBikesOccupiedAsync();
|
||||
return new Result<BikesReservedOccupiedResponse>(typeof(CopriCallsMonkeyStore), bikesOccupiedResponse, bikesOccupiedResponse.GetGeneralData(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +126,8 @@ namespace TINK.Model.Services.CopriApi
|
|||
{
|
||||
// No need to query because previous answer is not yet outdated.
|
||||
Log.ForContext<CopriProviderHttps>().Debug($"Returning stations from cache.");
|
||||
return new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetStationsAsync());
|
||||
var stationsResponse = await CacheServer.GetStationsAsync();
|
||||
return new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), stationsResponse, stationsResponse.GetGeneralData());
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -129,13 +138,15 @@ namespace TINK.Model.Services.CopriApi
|
|||
|
||||
return new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
stations.GetIsResponseOk("Abfrage der Stationen fehlsgeschlagen."));
|
||||
stations.GetIsResponseOk("Abfrage der Stationen fehlsgeschlagen."),
|
||||
stations.GetGeneralData());
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Return response from cache.
|
||||
Log.ForContext<CopriProviderHttps>().Debug("An error occurred querrying stations. {Exception}.", exception);
|
||||
return new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetStationsAsync(), exception);
|
||||
var stationsResponse = await CacheServer.GetStationsAsync();
|
||||
return new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), stationsResponse, stationsResponse.GetGeneralData(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,14 +68,6 @@ namespace TINK.Model.Services.CopriApi
|
|||
public Task<ResponseBase> DoSubmitMiniSurvey(IDictionary<string, string> answers)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public Task<SubmitFeedbackResponse> DoSubmitFeedback(string bikeId, string messge, bool bIsBikeBroke, Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
/// <summary> Submits mini survey to copri server. </summary>
|
||||
/// <param name="answers">Collection of answers.</param>
|
||||
public Task<ResponseBase> DoSubmitMiniSurvey(IDictionary<string, string> answers)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
|
||||
public async Task<AuthorizationResponse> DoAuthorizationAsync(string p_strMailAddress, string p_strPassword, string p_strDeviceId)
|
||||
{
|
||||
|
|
22
TINKLib/Services/CopriApi/GeneralData.cs
Normal file
22
TINKLib/Services/CopriApi/GeneralData.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace TINK.Services.CopriApi
|
||||
{
|
||||
/// <summary> Holds general purpose data returned from COPRI. </summary>
|
||||
public class GeneralData
|
||||
{
|
||||
|
||||
public GeneralData(string merachantMessage = null, Version apiVersion = null)
|
||||
{
|
||||
MerchantMessage = merachantMessage ?? string.Empty;
|
||||
ApiVersion = apiVersion ?? new Version(0, 0);
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Message to be shown to user.</summary>
|
||||
public string MerchantMessage { get; private set; }
|
||||
|
||||
/// <summary> Version of COPRI api. 0.0 if version is not set</summary>
|
||||
public Version ApiVersion { get; private set; }
|
||||
}
|
||||
}
|
|
@ -1,23 +1,38 @@
|
|||
using System;
|
||||
using TINK.Services.CopriApi;
|
||||
|
||||
namespace TINK.Model.Services.CopriApi
|
||||
{
|
||||
public class Result<T> where T : class
|
||||
{
|
||||
public Result(Type source, T response, System.Exception exception = null)
|
||||
/// <summary>
|
||||
/// Constructs a result object.
|
||||
/// </summary>
|
||||
/// <param name="source">Type of source (data provider).</param>
|
||||
/// <param name="response">Requested data (bikes, station).</param>
|
||||
/// <param name="generalData">General data (common to all respones).</param>
|
||||
public Result(
|
||||
Type source,
|
||||
T response,
|
||||
GeneralData generalData,
|
||||
Exception exception = null)
|
||||
{
|
||||
Source = source ?? throw new ArgumentException(nameof(source));
|
||||
Response = response ?? throw new ArgumentException(nameof(response));
|
||||
GeneralData = generalData ?? new GeneralData();
|
||||
Exception = exception;
|
||||
}
|
||||
|
||||
/// <summary> Holds the copri respsonse</summary>
|
||||
/// <summary> Holds the requested data (bikes, stations and bikes).</summary>
|
||||
public T Response { get; }
|
||||
|
||||
/// <summary> Specifies the souce of the copri response.</summary>
|
||||
/// <summary> Holds the general purpose data (common to all responses).</summary>
|
||||
public GeneralData GeneralData { get; }
|
||||
|
||||
/// <summary> Specifies the source (type of provider) of the copri response.</summary>
|
||||
public Type Source { get; }
|
||||
|
||||
/// <summary> Holds the exception if a communication error occurred.</summary>
|
||||
public System.Exception Exception { get; private set; }
|
||||
public Exception Exception { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace TINK.Model.Services.CopriApi
|
|||
StationsAll = stations;
|
||||
Bikes = bikes;
|
||||
}
|
||||
|
||||
public StationDictionary StationsAll { get; }
|
||||
|
||||
public BikeCollection Bikes { get; }
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.2.0" />
|
||||
<PackageReference Include="Xam.Plugins.Messaging" Version="5.2.0" />
|
||||
<PackageReference Include="Xamarin.Essentials" Version="1.7.0" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2125" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2196" />
|
||||
<PackageReference Include="Xamarin.Forms.GoogleMaps" Version="3.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -15,9 +15,9 @@ using TINK.Model.User;
|
|||
using Xamarin.Essentials;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.MiniSurvey;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using TINK.Model;
|
||||
|
||||
namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
|
@ -162,10 +162,10 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
IsConnected = IsConnectedDelegate();
|
||||
|
||||
var feedBackUri = SelectedBike?.OperatorUri;
|
||||
MiniSurveyModel miniSurvey;
|
||||
BookingFinishedModel bookingFinished;
|
||||
try
|
||||
{
|
||||
miniSurvey = await ConnectorFactory(IsConnected).Command.DoReturn(
|
||||
bookingFinished = await ConnectorFactory(IsConnected).Command.DoReturn(
|
||||
SelectedBike,
|
||||
currentLocationDto);
|
||||
|
||||
|
@ -289,7 +289,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
return RequestHandlerFactory.Create(SelectedBike, IsConnectedDelegate, ConnectorFactory, Geolocation, LockService, ViewUpdateManager, SmartDevice, ViewService, BikesViewModel, ActiveUser);
|
||||
}
|
||||
#endif
|
||||
if (miniSurvey != null && miniSurvey.Questions.Count > 0)
|
||||
if (bookingFinished != null && bookingFinished.MiniSurvey.Questions.Count > 0)
|
||||
{
|
||||
await ViewService.PushModalAsync(ViewTypes.MiniSurvey);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ using TINK.Model.Bikes.Bike.BluetoothLock;
|
|||
using TINK.Model.User;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.MiniSurvey;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using TINK.Model;
|
||||
|
||||
namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
|
@ -273,10 +273,10 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
IsConnected = IsConnectedDelegate();
|
||||
|
||||
var feedBackUri = SelectedBike?.OperatorUri;
|
||||
MiniSurveyModel miniSurvey;
|
||||
BookingFinishedModel bookingFinished;
|
||||
try
|
||||
{
|
||||
miniSurvey = await ConnectorFactory(IsConnected).Command.DoReturn(
|
||||
bookingFinished = await ConnectorFactory(IsConnected).Command.DoReturn(
|
||||
SelectedBike,
|
||||
currentLocation != null
|
||||
? new LocationDto.Builder
|
||||
|
@ -404,7 +404,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
}
|
||||
#endif
|
||||
|
||||
if (miniSurvey != null && miniSurvey.Questions.Count > 0)
|
||||
if (bookingFinished != null && bookingFinished.MiniSurvey.Questions.Count > 0)
|
||||
{
|
||||
await ViewService.PushModalAsync(ViewTypes.MiniSurvey);
|
||||
}
|
||||
|
|
|
@ -293,7 +293,6 @@ namespace TINK.ViewModel.BikesAtStation
|
|||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if bluetooth is activated.
|
||||
|
|
|
@ -408,7 +408,7 @@ namespace TINK.ViewModel.Contact
|
|||
}
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
Log.ForContext<SelectStationPageViewModel>().Error($"An error occurred switching view TINK/ Konrad.\r\n{l_oException.Message}");
|
||||
Log.ForContext<SelectStationPageViewModel>().Error($"An error occurred opening select station page.\r\n{l_oException.Message}");
|
||||
|
||||
IsRunning = false;
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@ namespace TINK.ViewModel
|
|||
// 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.FILTERTINKGENERAL, Model.Connector.FilterHelper.FILTERKONRAD }).Any()
|
||||
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);
|
||||
|
||||
|
@ -314,7 +314,7 @@ namespace TINK.ViewModel
|
|||
|
||||
try
|
||||
{
|
||||
if (!TinkApp.ActiveUser.Group.Contains(Model.Connector.FilterHelper.FILTERTINKGENERAL))
|
||||
if (!TinkApp.ActiveUser.Group.Contains(Model.Connector.FilterHelper.CARGOBIKE))
|
||||
{
|
||||
// No need to show "Anleitung TINK Räder" because user can not use tink.
|
||||
#if USEFLYOUT
|
||||
|
|
|
@ -314,34 +314,7 @@ namespace TINK.ViewModel.Map
|
|||
ActiveFilterMap = TinkApp.GroupFilterMapPage;
|
||||
|
||||
ActionText = AppResources.ActivityTextRequestingLocationPermissions;
|
||||
|
||||
// Check location permission
|
||||
var status = await PermissionsService.CheckStatusAsync();
|
||||
if (TinkApp.CenterMapToCurrentLocation
|
||||
&& !GeolocationService.IsSimulation
|
||||
&& status != Status.Granted)
|
||||
{
|
||||
var permissionResult = await PermissionsService.RequestAsync();
|
||||
|
||||
if (permissionResult != Status.Granted)
|
||||
{
|
||||
var dialogResult = await ViewService.DisplayAlert(
|
||||
AppResources.MessageTitleHint,
|
||||
AppResources.MessageCenterMapLocationPermissionOpenDialog,
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
if (dialogResult)
|
||||
{
|
||||
// User decided to give access to locations permissions.
|
||||
PermissionsService.OpenAppSettings();
|
||||
ActionText = "";
|
||||
IsRunning = false;
|
||||
IsMapPageEnabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
var status = await RequestLocationPermission();
|
||||
|
||||
ActionText = AppResources.ActivityTextMapLoadingStationsAndBikes;
|
||||
IsConnected = TinkApp.GetIsConnected();
|
||||
|
@ -349,63 +322,8 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
TinkApp.Stations = resultStationsAndBikes.Response.StationsAll;
|
||||
|
||||
if (Pins.Count > 0 && Pins.Count != resultStationsAndBikes.Response.StationsAll.Count)
|
||||
{
|
||||
// Either
|
||||
// - user logged in/ logged out which might lead to more/ less stations beeing available
|
||||
// - new stations were added/ existing ones remove
|
||||
Pins.Clear();
|
||||
}
|
||||
|
||||
// Check if there are alreay any pins to the map
|
||||
// i.e detecte first call of member OnAppearing after construction
|
||||
if (Pins.Count <= 0)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Debug($"{(ActiveFilterMap.GetGroup().Any() ? $"Active map filter is {string.Join(",", ActiveFilterMap.GetGroup())}." : "Map filter is off.")}");
|
||||
|
||||
// Map was not yet initialized.
|
||||
// Get stations from Copri
|
||||
Log.ForContext<MapPageViewModel>().Verbose("No pins detected on page.");
|
||||
if (resultStationsAndBikes.Response.StationsAll.CopriVersion < CopriCallsStatic.UnsupportedVersionLower)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageWaring,
|
||||
string.Format(AppResources.MessageCopriVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {resultStationsAndBikes.Response.StationsAll.CopriVersion}.");
|
||||
}
|
||||
|
||||
if (resultStationsAndBikes.Response.StationsAll.CopriVersion >= CopriCallsStatic.UnsupportedVersionUpper)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageWaring,
|
||||
string.Format(AppResources.MessageAppVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {resultStationsAndBikes.Response.StationsAll.CopriVersion}.");
|
||||
}
|
||||
|
||||
// Set pins to their positions on map.
|
||||
InitializePins(resultStationsAndBikes.Response.StationsAll);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Verbose("Update of pins done.");
|
||||
}
|
||||
|
||||
|
||||
if (resultStationsAndBikes.Exception?.GetType() == typeof(AuthcookieNotDefinedException))
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Map page is shown (probable for the first time after startup of app) and COPRI auth cookie is not defined. {@l_oException}", resultStationsAndBikes.Exception);
|
||||
|
||||
// COPRI reports an auth cookie error.
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.MessageMapPageErrorAuthcookieUndefined,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
await TinkApp.GetConnector(IsConnected).Command.DoLogout();
|
||||
TinkApp.ActiveUser.Logout();
|
||||
}
|
||||
await SetStationsOnMap(resultStationsAndBikes.Response.StationsAll);
|
||||
await HandleAuthCookieNotDefinedException(resultStationsAndBikes.Exception);
|
||||
|
||||
// Update pin colors.
|
||||
Log.ForContext<MapPageViewModel>().Verbose("Starting update pins color...");
|
||||
|
@ -417,21 +335,11 @@ namespace TINK.ViewModel.Map
|
|||
// Update pins color form count of bikes located at station.
|
||||
UpdatePinsColor(colors);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Verbose("Update pins color done.");
|
||||
|
||||
// Move and scale before getting stations and bikes which takes some time.
|
||||
ActionText = AppResources.ActivityTextCenterMap;
|
||||
Location currentLocation = null;
|
||||
try
|
||||
{
|
||||
currentLocation = TinkApp.CenterMapToCurrentLocation
|
||||
? await GeolocationService.GetAsync()
|
||||
: null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
|
||||
}
|
||||
|
||||
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.Uris.ActiveUri, ActiveFilterMap, currentLocation);
|
||||
await MoveMapToCurrentPositionOfUser(status);
|
||||
|
||||
m_oViewUpdateManager = CreateUpdateTask();
|
||||
|
||||
|
@ -467,6 +375,144 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the auth cookie is not defined.
|
||||
/// </summary>
|
||||
private async Task HandleAuthCookieNotDefinedException(Exception exception)
|
||||
{
|
||||
if (exception?.GetType() == typeof(AuthcookieNotDefinedException))
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Map page is shown (probable for the first time after startup of app) and COPRI auth cookie is not defined. {@l_oException}", exception);
|
||||
|
||||
// COPRI reports an auth cookie error.
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageWaring,
|
||||
AppResources.MessageMapPageErrorAuthcookieUndefined,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
await TinkApp.GetConnector(IsConnected).Command.DoLogout();
|
||||
TinkApp.ActiveUser.Logout();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the available stations on the map.
|
||||
/// </summary>
|
||||
private async Task SetStationsOnMap(StationDictionary stations)
|
||||
{
|
||||
if (Pins.Count > 0 && Pins.Count != stations.Count)
|
||||
{
|
||||
// Either
|
||||
// - user logged in/ logged out which might lead to more/ less stations beeing available
|
||||
// - new stations were added/ existing ones remove
|
||||
Pins.Clear();
|
||||
}
|
||||
|
||||
// Check if there are alreay any pins to the map
|
||||
// i.e detecte first call of member OnAppearing after construction
|
||||
if (Pins.Count <= 0)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Debug($"{(ActiveFilterMap.GetGroup().Any() ? $"Active map filter is {string.Join(",", ActiveFilterMap.GetGroup())}." : "Map filter is off.")}");
|
||||
|
||||
// Map was not yet initialized.
|
||||
// Get stations from Copri
|
||||
Log.ForContext<MapPageViewModel>().Verbose("No pins detected on page.");
|
||||
if (stations.CopriVersion < CopriCallsStatic.UnsupportedVersionLower)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageWaring,
|
||||
string.Format(AppResources.MessageCopriVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {stations.CopriVersion}.");
|
||||
}
|
||||
|
||||
if (stations.CopriVersion >= CopriCallsStatic.UnsupportedVersionUpper)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageWaring,
|
||||
string.Format(AppResources.MessageAppVersionIsOutdated, ContactPageViewModel.GetAppName(TinkApp.Uris.ActiveUri)),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {stations.CopriVersion}.");
|
||||
}
|
||||
|
||||
// Set pins to their positions on map.
|
||||
InitializePins(stations);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Verbose("Update of pins done.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the map to the current position of the user.
|
||||
/// If location permission hasn't been granted, the position is not adjusted.
|
||||
/// </summary>
|
||||
private async Task MoveMapToCurrentPositionOfUser(Status status)
|
||||
{
|
||||
if (status == Status.Granted)
|
||||
{
|
||||
ActionText = AppResources.ActivityTextCenterMap;
|
||||
if (TinkApp.CenterMapToCurrentLocation)
|
||||
{
|
||||
Location currentLocation = null;
|
||||
try
|
||||
{
|
||||
currentLocation = await GeolocationService.GetAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
|
||||
}
|
||||
|
||||
if (currentLocation != null)
|
||||
{
|
||||
TinkApp.UserMapSpan = MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(currentLocation.Latitude, currentLocation.Longitude),
|
||||
TinkApp.ActiveMapSpan.Radius);
|
||||
TinkApp.Save();
|
||||
}
|
||||
}
|
||||
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.ActiveMapSpan);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the location permission from the user.
|
||||
/// If the user declines, a dialog prompot is shown, telling the user to toggle the permission in the device settings.
|
||||
/// </summary>
|
||||
/// <returns>The permission status.</returns>
|
||||
private async Task<Status> RequestLocationPermission()
|
||||
{
|
||||
// Check location permission
|
||||
var status = await PermissionsService.CheckStatusAsync();
|
||||
if (TinkApp.CenterMapToCurrentLocation
|
||||
&& !GeolocationService.IsSimulation
|
||||
&& status != Status.Granted)
|
||||
{
|
||||
status = await PermissionsService.RequestAsync();
|
||||
|
||||
if (status != Status.Granted)
|
||||
{
|
||||
var dialogResult = await ViewService.DisplayAlert(
|
||||
AppResources.MessageTitleHint,
|
||||
AppResources.MessageCenterMapLocationPermissionOpenDialog,
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
if (dialogResult)
|
||||
{
|
||||
// User decided to give access to locations permissions.
|
||||
PermissionsService.OpenAppSettings();
|
||||
ActionText = "";
|
||||
IsRunning = false;
|
||||
IsMapPageEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/// <summary> Moves map and scales visible region depending on active filter. </summary>
|
||||
public static void MoveAndScale(
|
||||
Action<MapSpan> moveToRegionDelegate,
|
||||
|
@ -773,20 +819,20 @@ namespace TINK.ViewModel.Map
|
|||
/// <summary> User request to toggle from TINK to Konrad. </summary>
|
||||
public async Task ToggleTinkToKonrad()
|
||||
{
|
||||
if (tinkKonradToggleViewModel.CurrentFilter == FilterHelper.FILTERKONRAD)
|
||||
if (tinkKonradToggleViewModel.CurrentFilter == FilterHelper.CITYBIKE)
|
||||
{
|
||||
// Konrad is already activated, nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Information("User toggles to Konrad.");
|
||||
await ActivateFilter(FilterHelper.FILTERTINKGENERAL);
|
||||
await ActivateFilter(FilterHelper.CARGOBIKE);
|
||||
}
|
||||
|
||||
/// <summary> User request to toggle from TINK to Konrad. </summary>
|
||||
public async Task ToggleKonradToTink()
|
||||
{
|
||||
if (tinkKonradToggleViewModel.CurrentFilter == FilterHelper.FILTERTINKGENERAL)
|
||||
if (tinkKonradToggleViewModel.CurrentFilter == FilterHelper.CARGOBIKE)
|
||||
{
|
||||
// Konrad is already activated, nothing to do.
|
||||
return;
|
||||
|
@ -794,7 +840,7 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
Log.ForContext<MapPageViewModel>().Information("User toggles to TINK.");
|
||||
|
||||
await ActivateFilter(FilterHelper.FILTERKONRAD);
|
||||
await ActivateFilter(FilterHelper.CITYBIKE);
|
||||
}
|
||||
|
||||
/// <summary> User request to toggle from TINK to Konrad. </summary>
|
||||
|
@ -920,7 +966,7 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("An error occurred switching view TINK/ Konrad.{}");
|
||||
Log.ForContext<MapPageViewModel>().Error("An error occurred switching view Cargobike/ Citybike.{}");
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
"Fehler",
|
||||
|
|
|
@ -29,21 +29,21 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
|
||||
/// <summary> Gets value whether TINK is enabled or not. </summary>
|
||||
public bool IsTinkEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter.GetBikeCategory() != FilterHelper.FILTERTINKGENERAL;
|
||||
public bool IsTinkEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter.GetBikeCategory() != FilterHelper.CARGOBIKE;
|
||||
|
||||
/// <summary> Gets color of the TINK button. </summary>
|
||||
public Color TinkColor => CurrentFilter.GetBikeCategory() == FilterHelper.FILTERTINKGENERAL ? Color.Blue : Color.Gray;
|
||||
public Color TinkColor => CurrentFilter.GetBikeCategory() == FilterHelper.CARGOBIKE ? Color.Blue : Color.Gray;
|
||||
|
||||
/// <summary> Gets value whether Konrad is enabled or not. </summary>
|
||||
public bool IsKonradEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter.GetBikeCategory() != FilterHelper.FILTERKONRAD;
|
||||
public bool IsKonradEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter.GetBikeCategory() != FilterHelper.CITYBIKE;
|
||||
|
||||
/// <summary> Gets color of the Konrad button. </summary>
|
||||
public Color KonradColor => CurrentFilter.GetBikeCategory() == FilterHelper.FILTERKONRAD ? Color.Red : Color.Gray;
|
||||
public Color KonradColor => CurrentFilter.GetBikeCategory() == FilterHelper.CITYBIKE ? Color.Red : Color.Gray;
|
||||
|
||||
/// <summary> Gets whether toggle functionality is visible or not. </summary>
|
||||
public bool IsToggleVisible =>
|
||||
FilterDictionary.Select(x => x.Key).ContainsGroupId(FilterHelper.FILTERKONRAD)
|
||||
&& FilterDictionary.Select(x => x.Key).ContainsGroupId(FilterHelper.FILTERTINKGENERAL)
|
||||
FilterDictionary.Select(x => x.Key).ContainsGroupId(FilterHelper.CITYBIKE)
|
||||
&& FilterDictionary.Select(x => x.Key).ContainsGroupId(FilterHelper.CARGOBIKE)
|
||||
&& (IsTinkEnabled || IsKonradEnabled);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace TINK.ViewModel.Settings
|
|||
{
|
||||
foreach (var filter in filterSettings)
|
||||
{
|
||||
if (filter.Key == FilterHelper.FILTERTINKGENERAL)
|
||||
if (filter.Key == FilterHelper.CARGOBIKE)
|
||||
{
|
||||
Add(new FilterItemMutable(
|
||||
filter.Key,
|
||||
|
@ -29,7 +29,7 @@ namespace TINK.ViewModel.Settings
|
|||
AppResources.MarkingCargoBike));
|
||||
continue;
|
||||
}
|
||||
if (filter.Key == FilterHelper.FILTERKONRAD)
|
||||
if (filter.Key == FilterHelper.CITYBIKE)
|
||||
{
|
||||
Add(new FilterItemMutable(
|
||||
filter.Key,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue