mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-04-19 11:37:28 +02:00
Version 3.0.260
This commit is contained in:
parent
5a26bf273b
commit
4df8aa98aa
134 changed files with 8098 additions and 567 deletions
|
@ -70,6 +70,13 @@ namespace TINK.Model.Bikes.Bike
|
|||
/// Max. costs per day in euro.
|
||||
/// </summary>
|
||||
public double MaxFeeEuroPerDay { get; set; }
|
||||
|
||||
/// <summary> Info about operator agb as HTML (i.g. text and hyperlink). </summary>
|
||||
public string OperatorAgb { get; set; }
|
||||
|
||||
/// <summary> Text which informs users about GPS tracking if tracking is on. </summary>
|
||||
public string TrackingInfo { get; set; }
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace TINK.Model.Connector.Filter
|
|||
/// <summary> Applies filtering. </summary>
|
||||
/// <param name="filter">Enumeration of filter values to filter with or null if no filtering has to be applied.</param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<string> DoFilter(IEnumerable<string> filter) => filter != null
|
||||
? Group.Intersect(filter)
|
||||
: Group;
|
||||
public IEnumerable<string> DoFilter(IEnumerable<string> filter) => filter != null
|
||||
? Group.IntersectByGoupId(filter)
|
||||
: Group;
|
||||
}
|
||||
}
|
||||
|
|
43
TINKLib/Model/Connector/Filter/IntersectGroupFilterHelper.cs
Normal file
43
TINKLib/Model/Connector/Filter/IntersectGroupFilterHelper.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TINK.Model.Connector.Filter
|
||||
{
|
||||
public static class IntersectGroupFilterHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Transforms a group (each element consists of an operator prefix and a numeric bike category) to bike category enumeration (numeric elements).
|
||||
/// </summary>
|
||||
/// <param name="group">Group to transform.</param>
|
||||
/// <returns>Enumeration of numeric bike categories.</returns>
|
||||
public static IEnumerable<string> ToBikeCategory(this IEnumerable<string> group)
|
||||
=> group?.Select(x => x.GetBikeCategory())?.Where(x => !string.IsNullOrEmpty(x))
|
||||
?? new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Extracts bike group category umber from a group string.
|
||||
/// </summary>
|
||||
/// <param name="group">Group to transform. Example KN_300101 (Stadtrad located in Konstanz), FR_300102 (Lastenrad located in Freiburg).</param>
|
||||
/// <returns>Enumeration of numeric bike categories.</returns>
|
||||
public static string GetBikeCategory(this string group)
|
||||
=> Regex.Match(group, "[0-9]+")?.Value ?? string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Intersects two goups only taking into accout the numeric bike group category part.
|
||||
/// </summary>
|
||||
/// <param name="group">Group to filter.</param>
|
||||
/// <param name="filter">Filter to apply</param>
|
||||
public static IEnumerable<string> IntersectByGoupId(this IEnumerable<string> group, IEnumerable<string> filter)
|
||||
=> group.Where(x => filter.ContainsGroupId(x));
|
||||
|
||||
/// <summary>
|
||||
/// Gets if group contains a filter element.
|
||||
/// </summary>
|
||||
/// <param name="group"></param>
|
||||
/// <param name="filterElement"></param>
|
||||
/// <returns></returns>
|
||||
public static bool ContainsGroupId(this IEnumerable<string> group, string filterElement)
|
||||
=> group.ToBikeCategory().Contains(filterElement.GetBikeCategory());
|
||||
}
|
||||
}
|
|
@ -3,9 +3,17 @@
|
|||
public static class FilterHelper
|
||||
{
|
||||
/// <summary> Holds the Konrad group (city bikes).</summary>
|
||||
public const string FILTERKONRAD = "Konrad";
|
||||
/// <remarks>
|
||||
/// Was "Konrad" up to version 3.0.258.
|
||||
/// Specified first: "KN300001" (RG).
|
||||
/// </remarks>
|
||||
public const string FILTERKONRAD = "300101";
|
||||
|
||||
/// <summary> Holds the tink group (Lastenräder).</summary>
|
||||
public const string FILTERTINKGENERAL = "TINK";
|
||||
/// <remarks>
|
||||
/// Was "TINK" up to version 3.0.258.
|
||||
/// Specified first: "KN300029" (RG).
|
||||
/// </remarks>
|
||||
public const string FILTERTINKGENERAL = "300102";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,16 +86,6 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position from StationInfo object.
|
||||
/// </summary>
|
||||
/// <param name="p_oBikeInfo">Object to get information from.</param>
|
||||
/// <returns>Position information.</returns>
|
||||
public static Station.Position GetPosition(this BikeInfoAvailable p_oBikeInfo)
|
||||
{
|
||||
return GetPosition(p_oBikeInfo.gps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position from StationInfo object.
|
||||
/// </summary>
|
||||
|
|
|
@ -507,6 +507,8 @@ namespace TINK.Model.Connector
|
|||
FeeEuroPerHour = double.TryParse(tariffDesciption?.eur_per_hour, NumberStyles.Any, CultureInfo.InvariantCulture, out double euroPerHour) ? euroPerHour : double.NaN,
|
||||
AboEuroPerMonth = double.TryParse(tariffDesciption?.abo_eur_per_month, NumberStyles.Any, CultureInfo.InvariantCulture, out double aboEuroPerMonth) ? aboEuroPerMonth : double.NaN,
|
||||
MaxFeeEuroPerDay = double.TryParse(tariffDesciption?.max_eur_per_day, NumberStyles.Any, CultureInfo.InvariantCulture, out double maxEuroPerDay) ? maxEuroPerDay : double.NaN,
|
||||
OperatorAgb = tariffDesciption?.operator_agb,
|
||||
TrackingInfo = tariffDesciption?.track_info
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace TINK.Model
|
|||
{
|
||||
get
|
||||
{
|
||||
return new ViewModel.Map.GroupFilterMapPage(new Dictionary<string, FilterState> {
|
||||
return new GroupFilterMapPage(new Dictionary<string, FilterState> {
|
||||
{ FilterHelper.FILTERTINKGENERAL, FilterState.On },
|
||||
{FilterHelper.FILTERKONRAD, FilterState.Off }
|
||||
});
|
||||
|
|
|
@ -149,11 +149,6 @@ namespace TINK.Model.Settings
|
|||
return null;
|
||||
}
|
||||
|
||||
if (uriText.ToUpper().ToUpper().Contains("copri-bike.de".ToUpper()))
|
||||
return new Uri(CopriServerUriList.SHAREE_DEVEL);
|
||||
|
||||
if (uriText.ToUpper().ToUpper().Contains("copri.eu".ToUpper()))
|
||||
return new Uri(CopriServerUriList.SHAREE_LIVE);
|
||||
|
||||
return JsonConvert.DeserializeObject<Uri>(uriText);
|
||||
}
|
||||
|
|
|
@ -50,8 +50,8 @@ namespace TINK.Model.Settings
|
|||
bool? isSiteCachingOn = null,
|
||||
string activeTheme = null)
|
||||
{
|
||||
GroupFilterMapPage = groupFilterMapPage ?? GroupFilterHelper.GetMapPageFilterDefaults;
|
||||
GroupFilterSettings = groupFilterSettings ?? GroupFilterHelper.GetSettingsFilterDefaults;
|
||||
GroupFilterMapPage = groupFilterMapPage ?? new GroupFilterMapPage(); // Default behaviour: No filtering.
|
||||
GroupFilterSettings = groupFilterSettings ?? new GroupFilterSettings(); // Default behaviour: No filtering.
|
||||
ActiveUri = GetActiveUri(activeUri);
|
||||
PollingParameters = pollingParameters ?? PollingParameters.Default;
|
||||
MinimumLogEventLevel = minimumLogEventLevel ?? DEFAULTLOGGINLEVEL;
|
||||
|
|
|
@ -203,16 +203,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,7 +455,7 @@ namespace TINK.Model
|
|||
AppResources.ChangeLog3_0_250 // Third-party components updated.
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 254),
|
||||
new Version(3, 0, 260),
|
||||
// Same info as for version 3.0.251 and 3.0.252
|
||||
AppResources.ChangeLog3_0_231 // Minor improvements.
|
||||
}
|
||||
|
|
|
@ -1157,7 +1157,7 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to About {0}.
|
||||
/// Looks up a localized string similar to Legal Information.
|
||||
/// </summary>
|
||||
public static string MarkingAbout {
|
||||
get {
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<value>{0} Anfrage</value>
|
||||
</data>
|
||||
<data name="MarkingAbout" xml:space="preserve">
|
||||
<value>Über {0}</value>
|
||||
<value>Rechtliches</value>
|
||||
</data>
|
||||
<data name="MarkingAccount" xml:space="preserve">
|
||||
<value>Konto</value>
|
||||
|
|
|
@ -185,7 +185,7 @@ Bike can only be returned if bike is in reach and location information is avail
|
|||
<value>Opening phone app failed.</value>
|
||||
</data>
|
||||
<data name="MarkingAbout" xml:space="preserve">
|
||||
<value>About {0}</value>
|
||||
<value>Legal Information</value>
|
||||
</data>
|
||||
<data name="MarkingAccount" xml:space="preserve">
|
||||
<value>Account</value>
|
||||
|
|
|
@ -87,8 +87,8 @@
|
|||
<target state="final">{0} Anfrage</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingAbout" translate="yes" xml:space="preserve">
|
||||
<source>About {0}</source>
|
||||
<target state="final">Über {0}</target>
|
||||
<source>Legal Information</source>
|
||||
<target state="final">Rechtliches</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingAccount" translate="yes" xml:space="preserve">
|
||||
<source>Account</source>
|
||||
|
|
|
@ -62,6 +62,10 @@ namespace TINK.Repository.Response
|
|||
[DataMember]
|
||||
public TariffDescription tariff_description { get; private set; }
|
||||
#endif
|
||||
/// <summary> Loading state of motor battery in % ]0..100[. </summary>
|
||||
[DataMember]
|
||||
public string bike_charge { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Textual description of response.
|
||||
/// </summary>
|
||||
|
@ -70,6 +74,5 @@ namespace TINK.Repository.Response
|
|||
{
|
||||
return $"Bike {bike}{(station != null ? $", at station {station}" : string.Empty)}{(!string.IsNullOrEmpty(description) ? $", {description}" : string.Empty)}{(!string.IsNullOrEmpty(state) ? $", status={state}" : string.Empty)}.";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,5 +47,13 @@ namespace TINK.Repository.Response
|
|||
/// </summary>
|
||||
[DataMember]
|
||||
public string max_eur_per_day { get; private set; }
|
||||
|
||||
/// <summary> Info about operator agb as HTML (i.g. text and hyperlink). </summary>
|
||||
[DataMember]
|
||||
public string operator_agb { get; private set; }
|
||||
|
||||
/// <summary> Text which informs users about GPS tracking if tracking is on. </summary>
|
||||
[DataMember]
|
||||
public string track_info { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -66,5 +66,10 @@ namespace TINK.ViewModel.Bikes.Bike
|
|||
=> !double.IsNaN(Tariff.FeeEuroPerHour)
|
||||
? string.Format("{0} {1}", Tariff.MaxFeeEuroPerDay.ToString("0.00"), AppResources.MessageBikesManagementMaxFeeEuroPerDay)
|
||||
: string.Empty;
|
||||
|
||||
/// <summary> Info about operator agb as HTML (i.g. text and hyperlink). </summary>
|
||||
public string OperatorAgb => !string.IsNullOrEmpty(Tariff?.OperatorAgb)
|
||||
? Tariff.OperatorAgb
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace TINK.ViewModel.Map
|
|||
{
|
||||
return this.Where(x => x.Value == FilterState.On).Select(x => x.Key).ToList();
|
||||
}
|
||||
|
||||
/// <summary> Performs filtering on response-group. </summary>
|
||||
public IEnumerable<string> DoFilter(IEnumerable<string> filter = null) => Filter.DoFilter(filter);
|
||||
|
||||
|
@ -41,20 +42,11 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public void Add(string key, FilterState value)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public void Add(string key, FilterState value) => throw new System.NotImplementedException();
|
||||
|
||||
public void Add(KeyValuePair<string, FilterState> item) => throw new System.NotImplementedException();
|
||||
|
||||
public void Add(KeyValuePair<string, FilterState> item)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public void Clear() => throw new System.NotImplementedException();
|
||||
|
||||
public bool Contains(KeyValuePair<string, FilterState> item) => FilterDictionary.Contains(item);
|
||||
|
||||
|
@ -64,15 +56,9 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
public IEnumerator<KeyValuePair<string, FilterState>> GetEnumerator() => FilterDictionary.GetEnumerator();
|
||||
|
||||
public bool Remove(string key)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public bool Remove(string key) => throw new System.NotImplementedException();
|
||||
|
||||
public bool Remove(KeyValuePair<string, FilterState> item)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public bool Remove(KeyValuePair<string, FilterState> item) => throw new System.NotImplementedException();
|
||||
|
||||
public bool TryGetValue(string key, out FilterState value) => FilterDictionary.TryGetValue(key, out value);
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@ using TINK.Model;
|
|||
|
||||
namespace TINK.ViewModel.Map
|
||||
{
|
||||
public interface IGroupFilterMapPage : IDictionary<string, FilterState>
|
||||
/// <summary> Interface for filtering. </summary>
|
||||
/// <remarks> Holds a dictionary of filters which might or might not be appield depending on filter state.</remarks>
|
||||
public interface IGroupFilterMapPage : IDictionary<string /* Filter*/, FilterState /* on or off*/>
|
||||
{
|
||||
/// <summary> Performs filtering on response-group. </summary>
|
||||
IEnumerable<string> DoFilter(IEnumerable<string> filter = null);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Linq;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Connector.Filter;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.ViewModel.Map
|
||||
|
@ -28,21 +29,21 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
|
||||
/// <summary> Gets value whether TINK is enabled or not. </summary>
|
||||
public bool IsTinkEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter != FilterHelper.FILTERTINKGENERAL;
|
||||
public bool IsTinkEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter.GetBikeCategory() != FilterHelper.FILTERTINKGENERAL;
|
||||
|
||||
/// <summary> Gets color of the TINK button. </summary>
|
||||
public Color TinkColor => CurrentFilter == FilterHelper.FILTERTINKGENERAL ? Color.Blue : Color.Gray;
|
||||
public Color TinkColor => CurrentFilter.GetBikeCategory() == FilterHelper.FILTERTINKGENERAL ? Color.Blue : Color.Gray;
|
||||
|
||||
/// <summary> Gets value whether Konrad is enabled or not. </summary>
|
||||
public bool IsKonradEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter != FilterHelper.FILTERKONRAD;
|
||||
public bool IsKonradEnabled => !string.IsNullOrEmpty(CurrentFilter) && CurrentFilter.GetBikeCategory() != FilterHelper.FILTERKONRAD;
|
||||
|
||||
/// <summary> Gets color of the Konrad button. </summary>
|
||||
public Color KonradColor => CurrentFilter == FilterHelper.FILTERKONRAD ? Color.Red : Color.Gray;
|
||||
public Color KonradColor => CurrentFilter.GetBikeCategory() == FilterHelper.FILTERKONRAD ? Color.Red : Color.Gray;
|
||||
|
||||
/// <summary> Gets whether toggle functionality is visible or not. </summary>
|
||||
public bool IsToggleVisible =>
|
||||
FilterDictionary.ContainsKey(FilterHelper.FILTERKONRAD)
|
||||
&& FilterDictionary.ContainsKey(FilterHelper.FILTERTINKGENERAL)
|
||||
FilterDictionary.Select(x => x.Key).ContainsGroupId(FilterHelper.FILTERKONRAD)
|
||||
&& FilterDictionary.Select(x => x.Key).ContainsGroupId(FilterHelper.FILTERTINKGENERAL)
|
||||
&& (IsTinkEnabled || IsKonradEnabled);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -41,24 +41,8 @@ namespace TINK.Model.Connector
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the active uri.
|
||||
/// </summary>
|
||||
private Uri ActiveUri
|
||||
{
|
||||
set
|
||||
{
|
||||
if (m_oUris.ActiveUri.AbsoluteUri == value.AbsoluteUri)
|
||||
{
|
||||
/// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
m_oUris = new CopriServerUriList(m_oUris.Uris.ToArray(), value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets the known uris. </summary>
|
||||
/// <summary> Gets the known uris text, i.e. binds to picker ItemsSource. </summary>
|
||||
public IList<string> ServerTextList
|
||||
{
|
||||
get
|
||||
|
@ -70,7 +54,7 @@ namespace TINK.Model.Connector
|
|||
/// <summary> Holds the uri which will be applied after restart of app. </summary>
|
||||
public Uri NextActiveUri { get; private set; }
|
||||
|
||||
/// <summary> Holds the uri which will be applied after restart. </summary>
|
||||
/// <summary> Holds the active uri, i.e. binds to picker SelectedItem. </summary>
|
||||
public string NextActiveServerText
|
||||
{
|
||||
get
|
||||
|
@ -86,7 +70,7 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Holds the description of the picker.</summary>
|
||||
/// <summary> Holds the description of the picker, i.e. binds to label Text.</summary>
|
||||
public string CorpiServerUriDescription
|
||||
{
|
||||
get
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue