mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-21 21:46:27 +02:00
Version 3.0.346
This commit is contained in:
parent
1ba809dd59
commit
47c03f43fb
43 changed files with 609 additions and 117 deletions
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
|
@ -218,6 +218,12 @@ namespace TINK.ViewModel.Bikes
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
|
||||
// Empty collection.
|
||||
// Occurs in context of find bike page when searching for second, third, ... bike (reopen of page via flyout).
|
||||
ClearItems();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,11 +448,17 @@ namespace TINK.ViewModel.Bikes
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when page is shown.
|
||||
/// Starts update process.
|
||||
/// Invoked when page is shown and starts update process.
|
||||
/// </summary>
|
||||
/// <param name="updateAction"> Update fuction passed as argument by child class.</param>
|
||||
protected async Task OnAppearing(Action updateAction)
|
||||
=> await StartUpdateTask(updateAction);
|
||||
|
||||
/// <summary>
|
||||
/// Starts update process.
|
||||
/// </summary>
|
||||
/// <param name="updateAction"> Update fuction passed as argument by child class.</param>
|
||||
public async Task StartUpdateTask(Action updateAction)
|
||||
{
|
||||
m_oViewUpdateManager = new PollingUpdateTaskManager(updateAction);
|
||||
|
||||
|
@ -465,10 +477,7 @@ namespace TINK.ViewModel.Bikes
|
|||
/// Invoked when page is shutdown.
|
||||
/// Currently invoked by code behind, would be nice if called by XAML in future versions.
|
||||
/// </summary>
|
||||
public async Task OnDisappearing()
|
||||
{
|
||||
|
||||
await m_oViewUpdateManager.StopUpdatePeridically();
|
||||
}
|
||||
public virtual async Task OnDisappearing()
|
||||
=> await m_oViewUpdateManager.StopUpdatePeridically();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,11 @@ using TINK.Model.Bikes;
|
|||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Station;
|
||||
using TINK.Model.User;
|
||||
using TINK.MultilingualResources;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Services.Geolocation;
|
||||
|
@ -43,6 +45,7 @@ namespace TINK.ViewModel.FindBike
|
|||
}
|
||||
|
||||
bikeIdUserInput = value;
|
||||
base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(BikeIdUserInput)));
|
||||
base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsSelectBikeEnabled)));
|
||||
}
|
||||
}
|
||||
|
@ -123,14 +126,29 @@ namespace TINK.ViewModel.FindBike
|
|||
/// </summary>
|
||||
public async Task OnAppearing()
|
||||
{
|
||||
IsIdle = false;
|
||||
|
||||
Log.ForContext<FindBikePageViewModel>().Information("User request to show page FindBike- page re-appearing");
|
||||
|
||||
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
|
||||
if (string.IsNullOrEmpty(BikeIdUserInput) /* Find bike page flyout was taped */
|
||||
&& BikeCollection.Count > 0 /* Bike was successfully selected */)
|
||||
{
|
||||
// Find bike page flyout was taped and page was already opened before and bike has been selected.
|
||||
// Clear bike collection to allow user to enter bike id and search for bike.
|
||||
BikeCollection.Clear();
|
||||
}
|
||||
|
||||
var bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
|
||||
if (BikeCollection.Count > 0)
|
||||
{
|
||||
// Page is appearing not because page flyout was taped.
|
||||
// Bike has already been selected.
|
||||
// Restart update.
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
Exception = bikes.Exception; // Update communication error from query for bikes occupied.
|
||||
Bikes = bikes.Response;
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
|
@ -142,6 +160,48 @@ namespace TINK.ViewModel.FindBike
|
|||
/// <summary> Select a bike by ID</summary>
|
||||
public async Task SelectBike()
|
||||
{
|
||||
// Get List of bike to be able to connect to.
|
||||
ActionText = AppResources.ActivityTextFindBikeLoadingBikes;
|
||||
IsIdle = false;
|
||||
|
||||
Result<BikeCollection> bikes = null;
|
||||
try
|
||||
{
|
||||
bikes = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exception is WebConnectFailureException)
|
||||
{
|
||||
// Copri server is not reachable.
|
||||
Log.ForContext<FindBikePageViewModel>().Information("Getting bikes failed failed (Copri server not reachable).");
|
||||
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.ErrorReturnBikeNoWebTitle,
|
||||
string.Format("{0}\r\n{1}", AppResources.ErrorReturnBikeNoWebMessage, WebConnectFailureException.GetHintToPossibleExceptionsReasons),
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bikes failed. {Exception}", exception);
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageTitleHint,
|
||||
exception.Message,
|
||||
AppResources.MessageAnswerOk);
|
||||
}
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Exception = bikes?.Exception ?? null; // Update communication error from query for bikes occupied.
|
||||
Bikes = bikes.Response;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var selectedBike = Bikes.FirstOrDefault(x => x.Id.Equals(BikeIdUserInput.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
|
@ -152,6 +212,9 @@ namespace TINK.ViewModel.FindBike
|
|||
AppResources.MessageTitleHint,
|
||||
string.Format(AppResources.MessageErrorSelectBikeNoBikeFound, BikeIdUserInput),
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -193,7 +256,7 @@ namespace TINK.ViewModel.FindBike
|
|||
// User decided not to give access to locations permissions.
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
//await OnAppearing(() => UpdateTask());
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
|
@ -215,7 +278,7 @@ namespace TINK.ViewModel.FindBike
|
|||
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
await OnAppearing(() => UpdateTask());
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
|
@ -232,7 +295,7 @@ namespace TINK.ViewModel.FindBike
|
|||
|
||||
BikeCollection.Update(bikeCollection, Stations);
|
||||
|
||||
await OnAppearing(() => UpdateTask());
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
|
@ -259,7 +322,7 @@ namespace TINK.ViewModel.FindBike
|
|||
|
||||
BikeCollection.Update(bikeCollection.UpdateLockInfo(locksInfo), Stations);
|
||||
|
||||
await OnAppearing(() => UpdateTask());
|
||||
await StartUpdateTask(() => UpdateTask());
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
|
@ -272,6 +335,9 @@ namespace TINK.ViewModel.FindBike
|
|||
AppResources.MessageAnswerOk);
|
||||
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Running command to select bike failed. {Exception}", exception);
|
||||
|
||||
ActionText = "";
|
||||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Xamarin.Forms;
|
||||
using Xamarin.Forms;
|
||||
using TINK.View;
|
||||
using TINK.Model.Station;
|
||||
using System;
|
||||
|
@ -1028,4 +1028,4 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
public bool IsToggleVisible => tinkKonradToggleViewModel.IsToggleVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
TINKLib/ViewModel/Settings/PickerViewModel.cs
Normal file
18
TINKLib/ViewModel/Settings/PickerViewModel.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TINK.ViewModel.Settings
|
||||
{
|
||||
/// <summary> Manages data to be shown by a picker. </summary>
|
||||
public class PickerViewModel : ServicesViewModel
|
||||
{
|
||||
/// <summary>Constructs view model ensuring consistency. </summary>
|
||||
/// <param name="serviceToText"> Dictionary holding values and display text to mange and display by picker.</param>
|
||||
/// <param name="active">Value of entry for which the display text has to be shown.</param>
|
||||
public PickerViewModel(
|
||||
IDictionary<string, string> serviceToText,
|
||||
string active) : base(serviceToText.Select(x => x.Key), serviceToText, active)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
@ -8,6 +8,7 @@ using Serilog.Events;
|
|||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.MultilingualResources;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services;
|
||||
using TINK.Services.BluetoothLock;
|
||||
|
@ -44,6 +45,9 @@ namespace TINK.ViewModel
|
|||
/// <summary> Manages selection of locks services.</summary>
|
||||
public LocksServicesViewModel LocksServices { get; }
|
||||
|
||||
/// <summary>Settings determining the startup behavior of the app.</summary>
|
||||
public ServicesViewModel StartupSettings { get; }
|
||||
|
||||
/// <summary> Manages selection of geolocation services.</summary>
|
||||
public ServicesViewModel GeolocationServices { get; }
|
||||
|
||||
|
@ -155,6 +159,13 @@ namespace TINK.ViewModel
|
|||
{ typeof(GeolocationAccuracyBestService).FullName, "Best Accuracy" },
|
||||
{ typeof(SimulatedGeolocationService).FullName, "Simulation-AlwaysSamePosition" } },
|
||||
GeoloctionServicesContainer.Active.GetType().FullName);
|
||||
|
||||
StartupSettings = new PickerViewModel(
|
||||
new Dictionary<string, string> {
|
||||
{ ViewTypes.MapPage.ToString(), AppResources.MarkingMapPage },
|
||||
{ ViewTypes.FindBikePage.ToString(), AppResources.MarkingFindBike },
|
||||
},
|
||||
tinkApp.StartupSettings.StartupPage.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -259,6 +270,8 @@ namespace TINK.ViewModel
|
|||
TinkApp.GroupFilterMapPage,
|
||||
TinkApp.ActiveUser.DoFilter(TinkApp.FilterGroupSetting.DoFilter()));
|
||||
|
||||
TinkApp.StartupSettings.StartupPage = Enum.TryParse(StartupSettings.Active, out ViewTypes startupPage) ? startupPage : Model.Settings.StartupSettings.DefaultStartupPage;
|
||||
|
||||
TinkApp.CenterMapToCurrentLocation = CenterMapToCurrentLocation;
|
||||
|
||||
if (IsLogToExternalFolderVisible)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue