Small refactoring

This commit is contained in:
Tobias Reski 2021-11-09 16:08:00 +01:00
parent 34590fbc7d
commit ba3f987d2a
2 changed files with 141 additions and 114 deletions

View file

@ -22,7 +22,7 @@ namespace TINK.View.Map
private MapPageViewModel MapPageViewModel { get; set; }
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
private bool viewInitialized = false;
private bool isInitializationStarted = false;
/// <summary>
/// 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<MapPage>().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
return;
}
viewInitialized = true;
}
/// <summary>
/// Premoves the Map to a certain location.
/// </summary>
private void premoveAndScaleMap()
private void PremoveAndScaleMap()
{
Log.ForContext<MapPage>().Verbose("Moving and scaling map.");
MapPageViewModel.MoveAndScale(
@ -226,7 +226,7 @@ namespace TINK.View.Map
/// <summary>
/// Creates the Map Page's view model.
/// </summary>
private MapPageViewModel createMapPageViewModel()
private MapPageViewModel CreateMapPageViewModel()
{
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
return new MapPageViewModel(
@ -243,7 +243,7 @@ namespace TINK.View.Map
/// <summary>
/// Applies iOS specific styling to branded Buttons.
/// </summary>
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();
}
}

View file

@ -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<StationsAndBikesContainer> 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<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...");
@ -418,15 +337,13 @@ 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;
moveMapToCurrentPositionOfUser();
m_oViewUpdateManager = CreateUpdateTask();
Log.ForContext<MapPageViewModel>().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
}
}
/// <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 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<MapPageViewModel>().Error("Getting location failed. {Exception}", ex);
}
MoveAndScale(m_oMoveToRegionDelegate, TinkApp.Uris.ActiveUri, ActiveFilterMap, currentLocation);
};
}
/// <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 (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<MapPageViewModel>().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;
}
/// <summary> Moves map and scales visible region depending on active filter. </summary>