mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-04-22 21:06:30 +02:00
Merge branch 'master' into US-166/location-permission
# Conflicts: # TINK/TINK/View/Map/MapPage.xaml.cs # TINKLib/ViewModel/Map/MapPageViewModel.cs # TestFramework/Services/Permissions/PermissionsMock.cs # TestTINKLib/TestTINKLib.csproj
This commit is contained in:
commit
30c4e4879b
80 changed files with 2737 additions and 481 deletions
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TINK.Model.Connector.Filter
|
||||
{
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
/// Was "TINK" up to version 3.0.258.
|
||||
/// Specified first: "KN300029" (RG).
|
||||
/// </remarks>
|
||||
public const string FILTERTINKGENERAL = "300102";
|
||||
public const string FILTERTINKGENERAL = "300103";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,9 @@ namespace TINK.Model
|
|||
/// <summary> Value indicating whether map is centerted to current position or not. </summary>
|
||||
bool CenterMapToCurrentLocation { get; set; }
|
||||
|
||||
/// <summary> Holds the map area to display. </summary>
|
||||
Xamarin.Forms.GoogleMaps.MapSpan MapSpan { get; set; }
|
||||
|
||||
bool LogToExternalFolder { get; set; }
|
||||
|
||||
bool IsSiteCachingOn { get; set; }
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace TINK.ViewModel.Settings
|
|||
|
||||
private IGroupFilter Filter { get; }
|
||||
|
||||
/// <summary> Performs filtering on response-group. </summary>
|
||||
/// <summary> Performs filtering on response -group. </summary>
|
||||
public IEnumerable<string> DoFilter(IEnumerable<string> filter = null) => Filter.DoFilter(filter);
|
||||
|
||||
public FilterState this[string key] { get => FilterDictionary[key]; set => FilterDictionary[key] = value; }
|
||||
|
|
|
@ -495,11 +495,15 @@ namespace TINK.Model.Settings
|
|||
// Process legacy entries.
|
||||
var updatedFilterCollection = legacyFilterCollection.Where(x => x.Key.ToUpper() != "TINK.SMS" && x.Key.ToUpper() != "TINK.COPRI").ToDictionary(x => x.Key, x => x.Value);
|
||||
if (legacyFilterCollection.Count() <= updatedFilterCollection.Count())
|
||||
{
|
||||
// No legacy entries "INK.SMS" or "TINK.COPRI" found.
|
||||
return legacyFilterCollection;
|
||||
}
|
||||
|
||||
var list = updatedFilterCollection.ToList();
|
||||
|
||||
updatedFilterCollection.Add(
|
||||
FilterHelper.FILTERTINKGENERAL,
|
||||
"TINK",
|
||||
legacyFilterCollection.Any(x => x.Key.ToUpper() == "TINK.COPRI") ? legacyFilterCollection.FirstOrDefault(x => x.Key.ToUpper() == "TINK.COPRI").Value : FilterState.Off);
|
||||
|
||||
return new GroupFilterSettings(updatedFilterCollection);
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace TINK.Model.Settings
|
|||
TimeSpan? connectTimeout = null,
|
||||
string activeGeolocationService = null,
|
||||
bool? centerMapToCurrentLocation = null,
|
||||
Xamarin.Forms.GoogleMaps.MapSpan mapSpan = null,
|
||||
bool? logToExternalFolder = null,
|
||||
bool? isSiteCachingOn = null,
|
||||
string activeTheme = null)
|
||||
|
@ -61,6 +62,7 @@ namespace TINK.Model.Settings
|
|||
ConnectTimeout = connectTimeout ?? new TimeSpan(0, 0, TimeOutProvider.DEFAULT_BLUETOOTHCONNECT_TIMEOUTSECONDS); // Try one sec. to connect.
|
||||
ActiveGeolocationService = activeGeolocationService ?? DefaultLocationService.Name;
|
||||
CenterMapToCurrentLocation = centerMapToCurrentLocation ?? GetCenterMapToCurrentLocation(activeUri);
|
||||
MapSpan = mapSpan;
|
||||
LogToExternalFolder = logToExternalFolder ?? false;
|
||||
IsSiteCachingOn = isSiteCachingOn ?? true;
|
||||
ActiveTheme = activeTheme ?? typeof(Themes.ShareeBike).FullName;
|
||||
|
@ -93,8 +95,12 @@ namespace TINK.Model.Settings
|
|||
/// <summary> Gets the geolocation service to use.</summary>
|
||||
public string ActiveGeolocationService { get; }
|
||||
|
||||
/// <summary> True if map is centered to current positon, false if not to center map.</summary>
|
||||
public bool CenterMapToCurrentLocation { get; }
|
||||
|
||||
/// <summary> Holds the map area to display. </summary>
|
||||
public Xamarin.Forms.GoogleMaps.MapSpan MapSpan { get; }
|
||||
|
||||
public bool LogToExternalFolder { get; }
|
||||
|
||||
public bool IsSiteCachingOn { get; }
|
||||
|
|
|
@ -64,6 +64,9 @@ namespace TINK.Model
|
|||
/// <summary> Value indicating whether map is centerted to current position or not. </summary>
|
||||
public bool CenterMapToCurrentLocation { get; set; }
|
||||
|
||||
/// <summary> Holds the map area to display. </summary>
|
||||
public Xamarin.Forms.GoogleMaps.MapSpan MapSpan { get; set; }
|
||||
|
||||
/// <summary> Gets the minimum logging level. </summary>
|
||||
public LogEventLevel MinimumLogEventLevel { get; set; }
|
||||
|
||||
|
@ -206,6 +209,8 @@ namespace TINK.Model
|
|||
|
||||
CenterMapToCurrentLocation = settings.CenterMapToCurrentLocation;
|
||||
|
||||
MapSpan = settings.MapSpan;
|
||||
|
||||
SmartDevice = device
|
||||
?? throw new ArgumentException("Can not instantiate TinkApp- object. No device information provider available.");
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.Themes.Konrad">
|
||||
<!-- Pallete -->
|
||||
<!-- Red #ff0000 -->
|
||||
<Color x:Key="primary-back-title-color">Red</Color>
|
||||
<!-- Pallete-end -->
|
||||
<Style ApplyToDerivedTypes="true" TargetType="NavigationPage">
|
||||
|
|
|
@ -158,9 +158,7 @@ namespace TINK.ViewModel.Account
|
|||
return AppResources.MarkingLoggedInStateInfoNotLoggedIn;
|
||||
}
|
||||
|
||||
return TinkApp.ActiveUser.Group.Intersect(new List<string> { FilterHelper.FILTERTINKGENERAL, FilterHelper.FILTERKONRAD }).Any()
|
||||
? string.Format(AppResources.MarkingLoggedInStateInfoLoggedInGroup, TinkApp.ActiveUser.Mail, TinkApp.ActiveUser.GetUserGroupDisplayName())
|
||||
: string.Format(AppResources.MarkingLoggedInStateInfoLoggedIn, TinkApp.ActiveUser.Mail);
|
||||
return string.Format(AppResources.MarkingLoggedInStateInfoLoggedIn, TinkApp.ActiveUser.Mail);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ using Xamarin.Essentials;
|
|||
using System.Threading;
|
||||
using TINK.MultilingualResources;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using TINK.ViewModel.Info;
|
||||
using TINK.Repository;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
|
@ -208,7 +207,7 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
var l_oPin = new Pin
|
||||
{
|
||||
|
||||
|
||||
Position = new Xamarin.Forms.GoogleMaps.Position(station.Position.Latitude, station.Position.Longitude),
|
||||
Label = long.TryParse(station.Id, out long stationId) && stationId > CUSTOM_ICONS_COUNT
|
||||
? station.GetStationName()
|
||||
|
@ -232,13 +231,13 @@ namespace TINK.ViewModel.Map
|
|||
for (int pinIndex = 0; pinIndex < stationsColorList.Count; pinIndex++)
|
||||
{
|
||||
|
||||
var indexPartPrefix = int.TryParse(Pins[pinIndex].Tag.ToString(), out int stationId)
|
||||
var indexPartPrefix = int.TryParse(Pins[pinIndex].Tag.ToString(), out int stationId)
|
||||
&& stationId <= CUSTOM_ICONS_COUNT
|
||||
? $"{stationId}" // there is a station marker with index letter for given station id
|
||||
: "Open"; // there is no station marker. Use open marker.
|
||||
|
||||
var colorPartPrefix = GetRessourceNameColorPart(stationsColorList[pinIndex]);
|
||||
|
||||
|
||||
var l_iName = $"{indexPartPrefix.ToString().PadLeft(2, '0')}_{colorPartPrefix}{(DeviceInfo.Platform == DevicePlatform.Android ? ".png" : string.Empty)}";
|
||||
try
|
||||
{
|
||||
|
@ -293,7 +292,7 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
/// <param name="p_oFilterDictionaryMapPage">Holds map page filter settings.</param>
|
||||
|
@ -308,10 +307,10 @@ namespace TINK.ViewModel.Map
|
|||
Polling = TinkApp.Polling;
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Information(
|
||||
$"{(Polling != null && Polling.IsActivated ? $"Map page is appearing. Update periode is {Polling.Periode.TotalSeconds} sec." : "Map page is appearing. Polling is off.")}" +
|
||||
$"{(Polling != null && Polling.IsActivated ? $"Map page is appearing. Update periode is {Polling.Periode.TotalSeconds} sec." : "Map page is appearing. Polling is off.")}" +
|
||||
$"Current UI language is {Thread.CurrentThread.CurrentUICulture.Name}.");
|
||||
|
||||
// Update map page filter
|
||||
// Update map page filter
|
||||
ActiveFilterMap = TinkApp.GroupFilterMapPage;
|
||||
|
||||
ActionText = AppResources.ActivityTextRequestingLocationPermissions;
|
||||
|
@ -325,7 +324,7 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
await SetStationsOnMap(resultStationsAndBikes.Response.StationsAll);
|
||||
await HandleAuthCookieNotDefinedException(resultStationsAndBikes.Exception);
|
||||
|
||||
|
||||
|
||||
// Update pin colors.
|
||||
Log.ForContext<MapPageViewModel>().Verbose("Starting update pins color...");
|
||||
|
@ -378,7 +377,7 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the auth cookie is not defined.
|
||||
/// Invoked when the auth cookie is not defined.
|
||||
/// </summary>
|
||||
private async Task HandleAuthCookieNotDefinedException(Exception exception)
|
||||
{
|
||||
|
@ -410,7 +409,7 @@ namespace TINK.ViewModel.Map
|
|||
Pins.Clear();
|
||||
}
|
||||
|
||||
// Check if there are alreay any pins to the map
|
||||
// Check if there are alreay any pins to the map
|
||||
// i.e detecte first call of member OnAppearing after construction
|
||||
if (Pins.Count <= 0)
|
||||
{
|
||||
|
@ -439,8 +438,8 @@ namespace TINK.ViewModel.Map
|
|||
Log.ForContext<MapPageViewModel>().Error($"Outdated version of app detected. Version expected is {stations.CopriVersion}.");
|
||||
}
|
||||
|
||||
// Set pins to their positions on map.
|
||||
InitializePins(stations);
|
||||
// Set pins to their positions on map.
|
||||
InitializePins(resultStationsAndBikes.Response.StationsAll);
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Verbose("Update of pins done.");
|
||||
}
|
||||
|
@ -457,20 +456,27 @@ namespace TINK.ViewModel.Map
|
|||
Status status = await RequestLocationPermission();
|
||||
if (status == Status.Granted)
|
||||
{
|
||||
Location currentLocation = null;
|
||||
try
|
||||
ActionText = AppResources.ActivityTextCenterMap;
|
||||
if (TinkApp.CenterMapToCurrentLocation)
|
||||
{
|
||||
currentLocation = TinkApp.CenterMapToCurrentLocation
|
||||
? await GeolocationService.GetAsync()
|
||||
: null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
|
||||
}
|
||||
Location currentLocation = null;
|
||||
try
|
||||
{
|
||||
currentLocation = await GeolocationService.GetAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
|
||||
}
|
||||
|
||||
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.Uris.ActiveUri, ActiveFilterMap, currentLocation);
|
||||
};
|
||||
TinkApp.MapSpan = MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(currentLocation.Latitude, currentLocation.Longitude),
|
||||
TinkApp.MapSpan.Radius);
|
||||
|
||||
TinkApp.Save();
|
||||
}
|
||||
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.MapSpan);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -512,44 +518,14 @@ namespace TINK.ViewModel.Map
|
|||
/// <summary> Moves map and scales visible region depending on active filter. </summary>
|
||||
public static void MoveAndScale(
|
||||
Action<MapSpan> moveToRegionDelegate,
|
||||
Uri activeUri,
|
||||
IGroupFilterMapPage groupFilterMapPage,
|
||||
Location currentLocation = null)
|
||||
MapSpan currentMapSpan = null)
|
||||
{
|
||||
if (currentLocation != null)
|
||||
if (currentMapSpan != null)
|
||||
{
|
||||
// Move to current location.
|
||||
moveToRegionDelegate(MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(currentLocation.Latitude, currentLocation.Longitude),
|
||||
Distance.FromKilometers(1.0)));
|
||||
moveToRegionDelegate(currentMapSpan);
|
||||
return;
|
||||
}
|
||||
|
||||
if (activeUri.AbsoluteUri == CopriServerUriList.SHAREE_LIVE ||
|
||||
activeUri.AbsoluteUri == CopriServerUriList.SHAREE_DEVEL)
|
||||
{
|
||||
// Center map to Freiburg
|
||||
moveToRegionDelegate(MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(47.995865, 7.815086),
|
||||
Distance.FromKilometers(2.9)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Depending on whether TINK or Conrad is active set center of map and scale.
|
||||
if (groupFilterMapPage.GetGroup().Contains(FilterHelper.FILTERKONRAD))
|
||||
{
|
||||
// Konrad is activated,
|
||||
moveToRegionDelegate(MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(47.680, 9.180),
|
||||
Distance.FromKilometers(2.9)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TINK
|
||||
moveToRegionDelegate(MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(47.667, 9.172),
|
||||
Distance.FromKilometers(0.9)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Creates a update task object. </summary>
|
||||
|
@ -582,7 +558,7 @@ namespace TINK.ViewModel.Map
|
|||
Log.ForContext<MapPageViewModel>().Error("Getting bikes and stations in polling context failed with exception {Exception}.", exception);
|
||||
}
|
||||
|
||||
// Check if there are alreay any pins to the map.
|
||||
// Check if there are alreay any pins to the map.
|
||||
// If no initialze pins.
|
||||
if (Pins.Count <= 0)
|
||||
{
|
||||
|
@ -627,7 +603,7 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Invoked when pages is closed/ hidden.
|
||||
/// Stops update process.
|
||||
/// </summary>
|
||||
public async Task OnDisappearing()
|
||||
|
@ -648,7 +624,7 @@ namespace TINK.ViewModel.Map
|
|||
// Lock action to prevent multiple instances of "BikeAtStation" being opened.
|
||||
IsMapPageEnabled = false;
|
||||
|
||||
TinkApp.SelectedStation = TinkApp.Stations.FirstOrDefault(x => x.Id == selectedStationId)
|
||||
TinkApp.SelectedStation = TinkApp.Stations.FirstOrDefault(x => x.Id == selectedStationId)
|
||||
?? new Station(selectedStationId, new List<string>(), null); // Station might not be in list StationDictinaly because this list is not updatd in background task.
|
||||
|
||||
#if TRYNOTBACKSTYLE
|
||||
|
@ -904,7 +880,7 @@ namespace TINK.ViewModel.Map
|
|||
if (permissionResult != Status.Granted)
|
||||
{
|
||||
var dialogResult = await ViewService.DisplayAlert(
|
||||
AppResources.MessageTitleHint,
|
||||
AppResources.MessageTitleHint,
|
||||
AppResources.MessageBikesManagementLocationPermission,
|
||||
"Ja",
|
||||
"Nein");
|
||||
|
@ -919,14 +895,14 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
}
|
||||
|
||||
// Do not use property .State to get bluetooth state due
|
||||
// to issue https://hausource.visualstudio.com/TINK/_workitems/edit/116 /
|
||||
// Do not use property .State to get bluetooth state due
|
||||
// to issue https://hausource.visualstudio.com/TINK/_workitems/edit/116 /
|
||||
// see https://github.com/xabre/xamarin-bluetooth-le/issues/112#issuecomment-380994887
|
||||
if (await BluetoothService.GetBluetoothState() != Plugin.BLE.Abstractions.Contracts.BluetoothState.On)
|
||||
{
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageTitleHint,
|
||||
AppResources.MessageBikesManagementBluetoothActivation,
|
||||
AppResources.MessageBikesManagementBluetoothActivation,
|
||||
AppResources.MessageAnswerOk);
|
||||
IsMapPageEnabled = true;
|
||||
ActionText = "";
|
||||
|
@ -935,21 +911,27 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
|
||||
// Move and scale before getting stations and bikes which takes some time.
|
||||
Location currentLocation = null;
|
||||
try
|
||||
if (TinkApp.CenterMapToCurrentLocation)
|
||||
{
|
||||
currentLocation = TinkApp.CenterMapToCurrentLocation
|
||||
? await GeolocationService.GetAsync()
|
||||
: null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
|
||||
Location currentLocation = null;
|
||||
try
|
||||
{
|
||||
currentLocation = await GeolocationService.GetAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
|
||||
}
|
||||
|
||||
TinkApp.MapSpan = MapSpan.FromCenterAndRadius(
|
||||
new Xamarin.Forms.GoogleMaps.Position(currentLocation.Latitude, currentLocation.Longitude),
|
||||
TinkApp.MapSpan.Radius);
|
||||
|
||||
TinkApp.Save();
|
||||
}
|
||||
|
||||
// Update stations
|
||||
// Depending on whether TINK or Conrad is active set center of map and scale.
|
||||
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.Uris.ActiveUri, ActiveFilterMap, currentLocation);
|
||||
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.MapSpan);
|
||||
|
||||
IsConnected = TinkApp.GetIsConnected();
|
||||
var resultStationsAndBikes = await TinkApp.GetConnector(IsConnected).Query.GetBikesAndStationsAsync();
|
||||
|
@ -998,4 +980,4 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
public bool IsToggleVisible => tinkKonradToggleViewModel.IsToggleVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue