diff --git a/TINK/TINK/View/Map/MapPage.xaml.cs b/TINK/TINK/View/Map/MapPage.xaml.cs
index 02a8d14..a2737a9 100644
--- a/TINK/TINK/View/Map/MapPage.xaml.cs
+++ b/TINK/TINK/View/Map/MapPage.xaml.cs
@@ -22,7 +22,7 @@ namespace TINK.View.Map
private MapPageViewModel MapPageViewModel { get; set; }
/// Initialization status to ensure initialization logic is not called multiple times.
- private bool viewInitialized = false;
+ private bool isInitializationStarted = false;
///
/// Constructs map page instance.
@@ -136,12 +136,13 @@ namespace TINK.View.Map
protected async override void OnAppearing()
{
// Don't repeat the initialization if it has been completed already.
- if (viewInitialized) return;
+ if (isInitializationStarted) return;
+ isInitializationStarted = true;
// Pass reference to member Navigation to show bikes at station x dialog.
try
{
- MapPageViewModel = createMapPageViewModel();
+ MapPageViewModel = CreateMapPageViewModel();
}
catch (Exception exception)
{
@@ -166,7 +167,7 @@ namespace TINK.View.Map
try
{
- applyCustomiOSStyling();
+ ApplyCustomiOSStyling();
}
catch (Exception exception)
{
@@ -188,7 +189,7 @@ namespace TINK.View.Map
try
{
// Pre move and scanle maps to avoid initial display of map in Rome.
- premoveAndScaleMap();
+ PremoveAndScaleMap();
}
catch(Exception exception)
{
@@ -206,14 +207,13 @@ namespace TINK.View.Map
Log.ForContext().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
return;
}
- viewInitialized = true;
}
///
/// Premoves the Map to a certain location.
///
- private void premoveAndScaleMap()
+ private void PremoveAndScaleMap()
{
Log.ForContext().Verbose("Moving and scaling map.");
MapPageViewModel.MoveAndScale(
@@ -226,7 +226,7 @@ namespace TINK.View.Map
///
/// Creates the Map Page's view model.
///
- private MapPageViewModel createMapPageViewModel()
+ private MapPageViewModel CreateMapPageViewModel()
{
Log.ForContext().Verbose("Constructing map page view model.");
return new MapPageViewModel(
@@ -243,7 +243,7 @@ namespace TINK.View.Map
///
/// Applies iOS specific styling to branded Buttons.
///
- private void applyCustomiOSStyling()
+ private void ApplyCustomiOSStyling()
{
if (Device.RuntimePlatform == Device.iOS)
{
@@ -267,7 +267,6 @@ namespace TINK.View.Map
// View model might be null.
await MapPageViewModel?.OnDisappearing();
}
- viewInitialized = false;
base.OnDisappearing();
}
}
diff --git a/TINKLib/ViewModel/Map/MapPageViewModel.cs b/TINKLib/ViewModel/Map/MapPageViewModel.cs
index 2d55ccc..f0923e2 100644
--- a/TINKLib/ViewModel/Map/MapPageViewModel.cs
+++ b/TINKLib/ViewModel/Map/MapPageViewModel.cs
@@ -316,97 +316,16 @@ namespace TINK.ViewModel.Map
ActionText = AppResources.ActivityTextRequestingLocationPermissions;
- // 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;
- }
- }
- }
-
ActionText = AppResources.ActivityTextMapLoadingStationsAndBikes;
IsConnected = TinkApp.GetIsConnected();
- var resultStationsAndBikes = await TinkApp.GetConnector(IsConnected).Query.GetBikesAndStationsAsync();
+
+ Result resultStationsAndBikes = await TinkApp.GetConnector(IsConnected).Query.GetBikesAndStationsAsync();
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().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().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().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().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().Verbose("Update of pins done.");
- }
-
-
- if (resultStationsAndBikes.Exception?.GetType() == typeof(AuthcookieNotDefinedException))
- {
- Log.ForContext().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().Verbose("Starting update pins color...");
@@ -418,15 +337,13 @@ namespace TINK.ViewModel.Map
// Update pins color form count of bikes located at station.
UpdatePinsColor(colors);
+ Log.ForContext().Verbose("Update pins color done.");
+
+
// Move and scale before getting stations and bikes which takes some time.
ActionText = AppResources.ActivityTextCenterMap;
-
- moveMapToCurrentPositionOfUser();
-
m_oViewUpdateManager = CreateUpdateTask();
- Log.ForContext().Verbose("Update pins color done.");
-
try
{
// Update bikes at station or my bikes depending on context.
@@ -441,6 +358,8 @@ namespace TINK.ViewModel.Map
ActionText = "";
IsRunning = false;
IsMapPageEnabled = true;
+
+ await MoveMapToCurrentPositionOfUser();
}
catch (Exception l_oException)
{
@@ -457,28 +376,137 @@ namespace TINK.ViewModel.Map
}
}
+
+ ///
+ /// Invoked when the auth cookie is not defined.
+ ///
+ private async Task HandleAuthCookieNotDefinedException(Exception exception)
+ {
+ if (exception?.GetType() == typeof(AuthcookieNotDefinedException))
+ {
+ Log.ForContext().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();
+ }
+ }
+
+ ///
+ /// Sets the available stations on the map.
+ ///
+ 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().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().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().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().Error($"Outdated version of app detected. Version expected is {stations.CopriVersion}.");
+ }
+
+ // Set pins to their positions on map.
+ InitializePins(stations);
+
+ Log.ForContext().Verbose("Update of pins done.");
+ }
+
+ }
+
///
/// Moves the map to the current position of the user.
/// If location permission hasn't been granted, the position is not adjusted.
///
- private async void moveMapToCurrentPositionOfUser()
+ private async Task MoveMapToCurrentPositionOfUser()
{
+
+ Status status = await RequestLocationPermission();
+ if (status == Status.Granted)
+ {
+ Location currentLocation = null;
+ try
+ {
+ currentLocation = TinkApp.CenterMapToCurrentLocation
+ ? await GeolocationService.GetAsync()
+ : null;
+ }
+ catch (Exception ex)
+ {
+ Log.ForContext().Error("Getting location failed. {Exception}", ex);
+ }
+
+ MoveAndScale(m_oMoveToRegionDelegate, TinkApp.Uris.ActiveUri, ActiveFilterMap, currentLocation);
+ };
+ }
+
+ ///
+ /// 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.
+ ///
+ /// The permission status.
+ private async Task RequestLocationPermission()
+ {
+ // Check location permission
var status = await PermissionsService.CheckStatusAsync();
- if (status != Status.Granted) return;
- Location currentLocation = null;
- try
+ if (TinkApp.CenterMapToCurrentLocation
+ && !GeolocationService.IsSimulation
+ && status != Status.Granted)
{
- currentLocation = TinkApp.CenterMapToCurrentLocation
- ? await GeolocationService.GetAsync()
- : null;
- }
- catch (Exception ex)
- {
- Log.ForContext().Error("Getting location failed. {Exception}", ex);
- }
+ status = await PermissionsService.RequestAsync();
- MoveAndScale(m_oMoveToRegionDelegate, TinkApp.Uris.ActiveUri, ActiveFilterMap, currentLocation);
+ 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;
}
/// Moves map and scales visible region depending on active filter.