Version 3.0.375

This commit is contained in:
Anja 2023-11-06 12:23:09 +01:00
parent 2c790239cb
commit ca080c87c0
194 changed files with 10092 additions and 10464 deletions

View file

@ -176,16 +176,16 @@
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable" Version="28.0.0.3" />
<PackageReference Include="Xamarin.AndroidX.Core">
<Version>1.10.1.2</Version>
<Version>1.12.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
<Version>1.4.0.2</Version>
<Version>1.6.0.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Palette">
<Version>1.0.0.19</Version>
<Version>1.0.0.21</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.3.1</Version>
<Version>1.3.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -196,7 +196,7 @@
<Version>1.8.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Common">
<Version>120.3.3.1</Version>
<Version>120.3.3.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2612" />
<PackageReference Include="Xamarin.Forms.AppLinks">
@ -206,10 +206,10 @@
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.3" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.3" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.4" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.4" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.5" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.5" />
</ItemGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
@ -231,7 +231,6 @@
<Compile Include="Model\Device\WebView.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\BluetoothLock\Arendi\Central.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.374" android:versionCode="374">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.375" android:versionCode="375">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

File diff suppressed because it is too large Load diff

View file

@ -56,9 +56,9 @@
<key>CFBundleDisplayName</key>
<string>LastenradBayern</string>
<key>CFBundleVersion</key>
<string>374</string>
<string>375</string>
<key>CFBundleShortVersionString</key>
<string>3.0.374</string>
<string>3.0.375</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict>

View file

@ -23,9 +23,6 @@ using TINK.Services.Permissions;
using TINK.View;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
#if ARENDI
using Arendi.BleLibrary.Local;
#endif
// Required for support of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
@ -177,13 +174,6 @@ namespace TINK
specialFolder: specialFolders,
cipher: new Cipher(),
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),
arendiCentral:
#if ARENDI
DependencyService.Get<ICentral>(),
#else
null,
#endif
postAction: (d, obj) => context.Post(d, obj),
currentVersion: appInfoService.Version,
lastVersion: lastVersion,
@ -202,19 +192,12 @@ namespace TINK
{
InitializeComponent();
#if USEFLYOUT
// Use flyout page.
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.Root.RootPage()) // Show whats new info.
: (Page)new View.Root.RootPage(); // Just start sharee- app
#else
// Check which page to show first.
var mainPage = new View.RootShell.AppShell();
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = mainPage) // Show whats new info.
: (Page)mainPage; // Just start sharee- app
#endif
}
/// <summary> Concatenates all log files to a single one. </summary>

View file

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using TINK.View.Map;
using TINK.ViewModel.Map;
using Xamarin.Forms;
@ -26,12 +26,7 @@ namespace TINK
/// <returns></returns>
static Page GetCurrentPage()
{
#if USEFLYOUT
return (Application.Current.MainPage as FlyoutPage)?.Detail.Navigation.NavigationStack.LastOrDefault();
#else
return Shell.Current.CurrentPage;
#endif
}
}

View file

@ -13,9 +13,7 @@
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)BackdoorMethodHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\BluetoothLock\Arendi\Central.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootShell\AppShellViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootFlyout\RootPageViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Account\AccountPage.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>AccountPage.xaml</DependentUpon>
@ -60,13 +58,6 @@
<DependentUpon>FlyoutHeader.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml.cs">
<DependentUpon>RootPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml.cs">
<DependentUpon>RootPageFlyout.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyoutMenuItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml.cs">
<DependentUpon>AppShell.xaml</DependentUpon>
</Compile>
@ -98,7 +89,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\ViewModelResourceHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootMasterDetail\Helper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\BikesAtStation\BikesAtStationPage.xaml.cs">
<DependentUpon>BikesAtStationPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -107,10 +97,6 @@
<DependentUpon>ContactPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml.cs">
<DependentUpon>BikeInfoCarouselPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml.cs">
<DependentUpon>InfoTabbedPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -119,9 +105,6 @@
<DependentUpon>LoginPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootMasterDetail\MainPageMenuItem.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Map\MapPage.xaml.cs">
<DependentUpon>MapPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -190,12 +173,6 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml">
<SubType>Designer</SubType>
@ -250,16 +227,6 @@
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml">
<SubType>Designer</SubType>

View file

@ -2,9 +2,6 @@ using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using TINK.ViewModel.Account;
@ -13,11 +10,7 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
namespace TINK.View.Account
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class AccountPage : ContentPage, IViewService, IDetailPage
#else
public partial class AccountPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
AccountPageViewModel m_oViewModel = null;
@ -87,18 +80,9 @@ namespace TINK.View.Account
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -109,20 +93,6 @@ namespace TINK.View.Account
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.

View file

@ -10,9 +10,6 @@ namespace TINK.View.BikesAtStation
using System.Threading;
using System.Threading.Tasks;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using TINK.Model;
using TINK.Services.BluetoothLock.Tdo;
@ -27,39 +24,16 @@ namespace TINK.View.BikesAtStation
using TINK.MultilingualResources;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class BikesAtStationPage : ContentPage, IViewService
#endif
{
private BikesAtStationPageViewModel m_oViewModel;
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
private bool isInitializationStarted = false;
#if TRYNOTBACKSTYLE
public BikesAtStationPage()
{
InitializeComponent();
var l_oModel = App.ModelRoot;
var l_oViewModel = new BikesAtStationPageViewModel(
l_oModel.BikesAtStation,
l_oModel.ActiveUser,
l_oModel.SelectedStation,
this);
BindingContext = l_oViewModel;
BikesAtStationListView.ItemsSource = l_oViewModel;
}
#else
public BikesAtStationPage()
{
}
#endif
/// <summary>
/// Invoked when page is shown.
@ -73,11 +47,6 @@ namespace TINK.View.BikesAtStation
if (m_oViewModel != null)
{
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearingOrRefresh();
@ -123,11 +92,6 @@ namespace TINK.View.BikesAtStation
InitializeComponent();
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
@ -147,10 +111,6 @@ namespace TINK.View.BikesAtStation
await m_oViewModel?.OnDisappearing();
}
#if BACKSTYLE
if (m_oNavigation!= null)
m_oNavigation.IsGestureEnabled = true; // Enables master- detail menu navigation again when page is unloaded.
#endif
}
/// <summary>
@ -200,18 +160,9 @@ namespace TINK.View.BikesAtStation
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
/// <summary> Creates and a page an shows it.</summary>
/// <remarks> When user is not logged in navigation to Login page is supported.</remarks>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
@ -229,22 +180,6 @@ namespace TINK.View.BikesAtStation
throw new NotImplementedException();
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#else

View file

@ -3,9 +3,6 @@ using System;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel.Info;
using Xamarin.Essentials;
using Xamarin.Forms;
@ -15,11 +12,7 @@ using TINK.Model;
namespace TINK.View.Contact
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class ContactPage : ContentPage, IViewService, IDetailPage
#else
public partial class ContactPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify view model if page appears. </summary>
private ContactPageViewModel ViewModel { get; set; }
@ -78,14 +71,9 @@ namespace TINK.View.Contact
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string title = null)
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -104,19 +92,12 @@ namespace TINK.View.Contact
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -126,12 +107,5 @@ namespace TINK.View.Contact
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail { set; private get; }
#endif
}
}

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -14,11 +11,7 @@ namespace TINK.View.Contact
using TINK.ViewModel.Contact;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SelectStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class SelectStationPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
@ -70,18 +63,9 @@ namespace TINK.View.Contact
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="type">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
@ -96,20 +80,12 @@ namespace TINK.View.Contact
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -119,11 +95,6 @@ namespace TINK.View.Contact
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
@ -135,9 +106,6 @@ namespace TINK.View.Contact
{
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
#if TRYNOTBACKSTYLE
SelectStationPageViewModel = new SelectStationPageViewModel();
#else
SelectStationPageViewModel = new SelectStationPageViewModel(
App.ModelRoot,
App.PermissionsService,
@ -146,7 +114,6 @@ namespace TINK.View.Contact
(mapspan) => MyMap.MoveToRegion(mapspan),
this,
Navigation);
#endif
}
catch (Exception exception)
{
@ -159,9 +126,6 @@ namespace TINK.View.Contact
{
BindingContext = SelectStationPageViewModel;
#if USEFLYOUT
SelectStationPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{

View file

@ -155,14 +155,9 @@ namespace TINK.View.FindBike
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using System;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -12,27 +9,19 @@ using Xamarin.Forms.Xaml;
namespace TINK.View.Login
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class LoginPage : ContentPage, IViewService, IDetailPage
#else
public partial class LoginPage : ContentPage, IViewService
#endif
{
public LoginPage()
{
InitializeComponent();
var l_oModel = App.ModelRoot;
#if !BACKSTYLE
var l_oViewModel = new LoginPageViewModel(
l_oModel,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
this);
LoginPageView.BindingContext = l_oViewModel;
#else
LoginPageView.BindingContext = new LoginPageViewModel(l_oModel.ActiveUser, this, Navigation);
#endif
}
/// <summary>
@ -66,19 +55,9 @@ namespace TINK.View.Login
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -99,21 +78,6 @@ namespace TINK.View.Login
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -13,11 +10,7 @@ namespace TINK.View.Map
using TINK.ViewModel.Map;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class MapPage : ContentPage, IViewService, IDetailPage
#else
public partial class MapPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private MapPageViewModel MapPageViewModel { get; set; }
@ -75,18 +68,9 @@ namespace TINK.View.Map
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
@ -101,19 +85,12 @@ namespace TINK.View.Map
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -124,11 +101,6 @@ namespace TINK.View.Map
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
@ -144,11 +116,7 @@ namespace TINK.View.Map
{
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
#if TRYNOTBACKSTYLE
MapPageViewModel = new MapPageViewModel();
#else
MapPageViewModel = CreateMapPageViewModel();
#endif
}
catch (Exception exception)
{
@ -161,9 +129,6 @@ namespace TINK.View.Map
{
BindingContext = MapPageViewModel;
#if USEFLYOUT
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{

View file

@ -68,14 +68,9 @@ namespace TINK.View.MiniSurvey
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -153,14 +150,9 @@ namespace TINK.View.MyBikes
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using Xamarin.CommunityToolkit.Extensions;
@ -13,11 +10,7 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
namespace TINK.View.Settings
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
#else
public partial class SettingsPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
SettingsPageViewModel m_oViewModel = null;
@ -89,18 +82,9 @@ namespace TINK.View.Settings
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -111,19 +95,6 @@ namespace TINK.View.Settings
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.

View file

@ -1,9 +1,8 @@
using System;
using System;
using TINK.View.BikesAtStation;
using TINK.View.Contact;
using TINK.View.CopriWebView;
using TINK.View.Info;
using TINK.View.Info.BikeInfo;
using TINK.View.Login;
using TINK.View.Map;
using TINK.View.MiniSurvey;
@ -33,9 +32,6 @@ namespace TINK.View
case ViewTypes.PasswordForgottenPage:
return typeof(PasswordForgottenPage);
case ViewTypes.BikeInfoCarouselPage:
return typeof(BikeInfoCarouselPage);
case ViewTypes.MyBikesPage:
return typeof(MyBikesPage);

View file

@ -65,14 +65,9 @@ namespace TINK.View.WhatsNew.Agb
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
=> throw new NotImplementedException();
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();

View file

@ -68,14 +68,9 @@ namespace TINK.View.WhatsNew
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();

View file

@ -9,7 +9,7 @@
<ItemGroup>
<PackageReference Include="Plugin.BLE" Version="2.1.3" />
<PackageReference Include="Polly" Version="7.2.4" />
<PackageReference Include="Polly" Version="8.1.0" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.8.0" />
</ItemGroup>

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LockItShared\LockItSharedCore.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Plugin.BLE" Version="2.1.3" />
<PackageReference Include="Polly" Version="7.2.4" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.8.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34031.279
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItBLECore", "LockItBLECore.csproj", "{6B1CBC2E-9644-4CEC-9CF5-BA68AE56E97A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItSharedCore", "..\LockItShared\LockItSharedCore.csproj", "{950B8542-5067-4EE9-A7EB-AB314FE3C1B0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6B1CBC2E-9644-4CEC-9CF5-BA68AE56E97A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B1CBC2E-9644-4CEC-9CF5-BA68AE56E97A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B1CBC2E-9644-4CEC-9CF5-BA68AE56E97A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B1CBC2E-9644-4CEC-9CF5-BA68AE56E97A}.Release|Any CPU.Build.0 = Release|Any CPU
{950B8542-5067-4EE9-A7EB-AB314FE3C1B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{950B8542-5067-4EE9-A7EB-AB314FE3C1B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{950B8542-5067-4EE9-A7EB-AB314FE3C1B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{950B8542-5067-4EE9-A7EB-AB314FE3C1B0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EB92666E-7E16-4AEB-9DA8-919E409198AF}
EndGlobalSection
EndGlobal

View file

@ -260,7 +260,7 @@ namespace TINK.Services.BluetoothLock.BLE
if (string.IsNullOrEmpty(name))
{
// Lock without name detected.
Log.ForContext<LockItByScanServiceBase>().Debug($"Ble decvice without name discovered. RSSI={a.Device.Rssi}, GUID={a.Device.Id}, State={a.Device.State}.");
Log.ForContext<LockItByScanServiceBase>().Debug($"Ble device without name discovered. RSSI={a.Device.Rssi}, GUID={a.Device.Id}, State={a.Device.State}.");
return;
}

View file

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="3.0.1" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34031.279
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LockItSharedCore", "LockItSharedCore.csproj", "{44994E9A-4EC5-4E2E-8151-38AA0BE606D2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0E8EB534-0161-4A42-8F19-59BDBAD9C64D}"
ProjectSection(SolutionItems) = preProject
..\.editorconfig = ..\.editorconfig
..\.vsspell = ..\.vsspell
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{44994E9A-4EC5-4E2E-8151-38AA0BE606D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44994E9A-4EC5-4E2E-8151-38AA0BE606D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44994E9A-4EC5-4E2E-8151-38AA0BE606D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44994E9A-4EC5-4E2E-8151-38AA0BE606D2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9539C371-F0FB-47C0-B1B3-76875B4923FB}
EndGlobalSection
EndGlobal

View file

@ -175,16 +175,16 @@
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable" Version="28.0.0.3" />
<PackageReference Include="Xamarin.AndroidX.Core">
<Version>1.10.1.2</Version>
<Version>1.12.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
<Version>1.4.0.2</Version>
<Version>1.6.0.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Palette">
<Version>1.0.0.19</Version>
<Version>1.0.0.21</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.3.1</Version>
<Version>1.3.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -195,7 +195,7 @@
<Version>1.8.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Common">
<Version>120.3.3.1</Version>
<Version>120.3.3.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2612" />
<PackageReference Include="Xamarin.Forms.AppLinks">
@ -205,10 +205,10 @@
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.3" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.3" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.4" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.4" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.5" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.5" />
</ItemGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
@ -230,7 +230,6 @@
<Compile Include="Model\Device\WebView.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\BluetoothLock\Arendi\Central.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.374" android:versionCode="374">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.375" android:versionCode="375">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

File diff suppressed because it is too large Load diff

View file

@ -56,9 +56,9 @@
<key>CFBundleDisplayName</key>
<string>Mein konrad</string>
<key>CFBundleVersion</key>
<string>374</string>
<string>375</string>
<key>CFBundleShortVersionString</key>
<string>3.0.374</string>
<string>3.0.375</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict>

View file

@ -22,9 +22,6 @@ using TINK.Services.Permissions;
using TINK.View;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
#if ARENDI
using Arendi.BleLibrary.Local;
#endif
// Required for support of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
@ -178,12 +175,6 @@ namespace TINK
specialFolder: specialFolders,
cipher: new Cipher(),
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),
arendiCentral:
#if ARENDI
DependencyService.Get<ICentral>(),
#else
null,
#endif
postAction: (d, obj) => context.Post(d, obj),
currentVersion: appInfoService.Version,
lastVersion: lastVersion,
@ -202,19 +193,12 @@ namespace TINK
{
InitializeComponent();
#if USEFLYOUT
// Use flyout page.
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.Root.RootPage()) // Show whats new info.
: (Page)new View.Root.RootPage(); // Just start sharee- app
#else
// Check which page to show first.
var mainPage = new View.RootShell.AppShell();
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = mainPage) // Show whats new info.
: (Page)mainPage; // Just start sharee- app
#endif
}
/// <summary> Concatenates all log files to a single one. </summary>

View file

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using TINK.View.Map;
using TINK.ViewModel.Map;
using Xamarin.Forms;
@ -27,11 +27,7 @@ namespace TINK
static Page GetCurrentPage()
{
#if USEFLYOUT
return (Application.Current.MainPage as FlyoutPage)?.Detail.Navigation.NavigationStack.LastOrDefault();
#else
return Shell.Current.CurrentPage;
#endif
}
}

View file

@ -13,9 +13,7 @@
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)BackdoorMethodHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\BluetoothLock\Arendi\Central.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootShell\AppShellViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootFlyout\RootPageViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Account\AccountPage.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>%(Filename)</DependentUpon>
@ -64,13 +62,6 @@
<DependentUpon>FlyoutHeader.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml.cs">
<DependentUpon>RootPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml.cs">
<DependentUpon>RootPageFlyout.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyoutMenuItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml.cs">
<DependentUpon>AppShell.xaml</DependentUpon>
</Compile>
@ -102,7 +93,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\ViewModelResourceHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootMasterDetail\Helper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\BikesAtStation\BikesAtStationPage.xaml.cs">
<DependentUpon>BikesAtStationPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -111,10 +101,6 @@
<DependentUpon>ContactPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml.cs">
<DependentUpon>BikeInfoCarouselPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml.cs">
<DependentUpon>InfoTabbedPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -123,9 +109,6 @@
<DependentUpon>LoginPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootMasterDetail\MainPageMenuItem.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Map\MapPage.xaml.cs">
<DependentUpon>MapPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -194,12 +177,6 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml">
<SubType>Designer</SubType>
@ -254,16 +231,6 @@
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml">
<SubType>Designer</SubType>

View file

@ -2,9 +2,6 @@ using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using TINK.ViewModel.Account;
@ -13,11 +10,7 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
namespace TINK.View.Account
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class AccountPage : ContentPage, IViewService, IDetailPage
#else
public partial class AccountPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
AccountPageViewModel m_oViewModel = null;
@ -87,18 +80,9 @@ namespace TINK.View.Account
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -109,20 +93,6 @@ namespace TINK.View.Account
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.

View file

@ -36,7 +36,7 @@
Padding="0"
RowSpacing="15"
ColumnSpacing="5"
ColumnDefinitions="Auto,Auto,*"
ColumnDefinitions="Auto,*,Auto"
RowDefinitions="Auto,Auto,Auto">
<!-- Bike image -->
@ -45,6 +45,7 @@
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
HorizontalOptions="Start"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"/>
@ -55,6 +56,7 @@
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
HorizontalOptions="Start"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
IsVisible="{Binding IsBatteryChargeVisible}"/>
@ -73,12 +75,14 @@
<Label
Text="{Binding StateText}"
FontSize="Small"
LineBreakMode="WordWrap"
TextColor="{Binding StateColor}"/>
<!-- Rental state error info -->
<Label
Text="{Binding ErrorText}"
FontSize="Small"
LineBreakMode="WordWrap"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>

View file

@ -10,9 +10,6 @@ namespace TINK.View.BikesAtStation
using System.Threading;
using System.Threading.Tasks;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using TINK.Model;
using TINK.Services.BluetoothLock.Tdo;
@ -27,11 +24,7 @@ namespace TINK.View.BikesAtStation
using TINK.MultilingualResources;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class BikesAtStationPage : ContentPage, IViewService
#endif
{
private BikesAtStationPageViewModel m_oViewModel;
@ -39,28 +32,9 @@ namespace TINK.View.BikesAtStation
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
private bool isInitializationStarted = false;
#if TRYNOTBACKSTYLE
public BikesAtStationPage()
{
InitializeComponent();
var l_oModel = App.ModelRoot;
var l_oViewModel = new BikesAtStationPageViewModel(
l_oModel.BikesAtStation,
l_oModel.ActiveUser,
l_oModel.SelectedStation,
this);
BindingContext = l_oViewModel;
BikesAtStationListView.ItemsSource = l_oViewModel;
}
#else
public BikesAtStationPage()
{
}
#endif
/// <summary>
/// Invoked when page is shown.
@ -74,11 +48,6 @@ namespace TINK.View.BikesAtStation
if (m_oViewModel != null)
{
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearingOrRefresh();
@ -122,11 +91,6 @@ namespace TINK.View.BikesAtStation
InitializeComponent();
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
@ -146,10 +110,6 @@ namespace TINK.View.BikesAtStation
await m_oViewModel?.OnDisappearing();
}
#if BACKSTYLE
if (m_oNavigation!= null)
m_oNavigation.IsGestureEnabled = true; // Enables master- detail menu navigation again when page is unloaded.
#endif
}
/// <summary>
@ -199,17 +159,9 @@ namespace TINK.View.BikesAtStation
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
/// <summary> Creates and a page an shows it.</summary>
/// <remarks> When user is not logged in navigation to Login page is supported.</remarks>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
@ -228,21 +180,6 @@ namespace TINK.View.BikesAtStation
throw new NotImplementedException();
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());

View file

@ -3,9 +3,6 @@ using System;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel.Info;
using Xamarin.Essentials;
using Xamarin.Forms;
@ -15,12 +12,7 @@ using TINK.Model;
namespace TINK.View.Contact
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class ContactPage : ContentPage, IViewService, IDetailPage
#else
public partial class ContactPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify view model if page appears. </summary>
private ContactPageViewModel ViewModel { get; set; }
@ -79,14 +71,9 @@ namespace TINK.View.Contact
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string title = null)
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -105,19 +92,12 @@ namespace TINK.View.Contact
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -127,12 +107,5 @@ namespace TINK.View.Contact
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail { set; private get; }
#endif
}
}

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -13,11 +10,7 @@ namespace TINK.View.Contact
using TINK.ViewModel.Contact;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SelectStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class SelectStationPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
@ -72,18 +65,9 @@ namespace TINK.View.Contact
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="type">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
@ -98,19 +82,12 @@ namespace TINK.View.Contact
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -121,11 +98,6 @@ namespace TINK.View.Contact
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
@ -137,9 +109,6 @@ namespace TINK.View.Contact
{
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
#if TRYNOTBACKSTYLE
SelectStationPageViewModel = new SelectStationPageViewModel();
#else
SelectStationPageViewModel = new SelectStationPageViewModel(
App.ModelRoot,
App.PermissionsService,
@ -148,7 +117,6 @@ namespace TINK.View.Contact
(mapspan) => MyMap.MoveToRegion(mapspan),
this,
Navigation);
#endif
}
catch (Exception exception)
{
@ -161,9 +129,6 @@ namespace TINK.View.Contact
{
BindingContext = SelectStationPageViewModel;
#if USEFLYOUT
SelectStationPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{

View file

@ -154,14 +154,9 @@ namespace TINK.View.FindBike
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using System;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -12,11 +9,7 @@ using Xamarin.Forms.Xaml;
namespace TINK.View.Login
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class LoginPage : ContentPage, IViewService, IDetailPage
#else
public partial class LoginPage : ContentPage, IViewService
#endif
{
/// <summary> Reference to view model. </summary>
LoginPageViewModel m_oViewModel = null;
@ -27,16 +20,12 @@ namespace TINK.View.Login
InitializeComponent();
var l_oModel = App.ModelRoot;
#if !BACKSTYLE
m_oViewModel = new LoginPageViewModel(
l_oModel,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
this);
BindingContext = m_oViewModel;
#else
LoginPageView.BindingContext = new LoginPageViewModel(l_oModel.ActiveUser, this, Navigation);
#endif
}
/// <summary>
@ -70,18 +59,9 @@ namespace TINK.View.Login
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
@ -103,21 +83,6 @@ namespace TINK.View.Login
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -13,11 +10,7 @@ namespace TINK.View.Map
using TINK.ViewModel.Map;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class MapPage : ContentPage, IViewService, IDetailPage
#else
public partial class MapPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private MapPageViewModel MapPageViewModel { get; set; }
@ -75,18 +68,9 @@ namespace TINK.View.Map
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
@ -101,19 +85,12 @@ namespace TINK.View.Map
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -124,11 +101,6 @@ namespace TINK.View.Map
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
@ -144,11 +116,7 @@ namespace TINK.View.Map
{
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
#if TRYNOTBACKSTYLE
MapPageViewModel = new MapPageViewModel();
#else
MapPageViewModel = CreateMapPageViewModel();
#endif
}
catch (Exception exception)
{
@ -161,9 +129,6 @@ namespace TINK.View.Map
{
BindingContext = MapPageViewModel;
#if USEFLYOUT
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{

View file

@ -67,14 +67,9 @@ namespace TINK.View.MiniSurvey
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -153,14 +150,9 @@ namespace TINK.View.MyBikes
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using Xamarin.CommunityToolkit.Extensions;
@ -13,11 +10,7 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
namespace TINK.View.Settings
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
#else
public partial class SettingsPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
SettingsPageViewModel m_oViewModel = null;
@ -89,18 +82,9 @@ namespace TINK.View.Settings
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -111,19 +95,6 @@ namespace TINK.View.Settings
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.

View file

@ -1,9 +1,8 @@
using System;
using System;
using TINK.View.BikesAtStation;
using TINK.View.Contact;
using TINK.View.CopriWebView;
using TINK.View.Info;
using TINK.View.Info.BikeInfo;
using TINK.View.Login;
using TINK.View.Map;
using TINK.View.MiniSurvey;
@ -33,9 +32,6 @@ namespace TINK.View
case ViewTypes.PasswordForgottenPage:
return typeof(PasswordForgottenPage);
case ViewTypes.BikeInfoCarouselPage:
return typeof(BikeInfoCarouselPage);
case ViewTypes.MyBikesPage:
return typeof(MyBikesPage);

View file

@ -65,14 +65,9 @@ namespace TINK.View.WhatsNew.Agb
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
=> throw new NotImplementedException();
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();

View file

@ -68,14 +68,9 @@ namespace TINK.View.WhatsNew
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();

View file

@ -40,7 +40,7 @@
<Grid
Grid.Row="0"
IsVisible="True"
RowDefinitions="50,10"
RowDefinitions="50,Auto,10"
RowSpacing="0"
ColumnDefinitions="*,*">
@ -58,6 +58,7 @@
<Frame
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
BackgroundColor="{DynamicResource process-step-upcoming}"
Padding="14,2,10,2"
HasShadow="False">
@ -97,8 +98,10 @@
<Label
Grid.Column="0"
Text="{x:Static resources:AppResources.MarkingRentalProcessCloseLockFirstStep}"
FontSize="Medium"
FontSize="17"
FontAttributes="Bold"
LineBreakMode="WordWrap"
MaxLines="2"
TextColor="White">
<Label.Triggers>
<MultiTrigger TargetType="Label">
@ -177,7 +180,7 @@
</Frame>
<Polygon
Grid.Column="0"
Grid.Row="1"
Grid.Row="2"
Points="0,0 20,0 10,10"
IsVisible="False"
HorizontalOptions="Center">
@ -212,6 +215,7 @@
<Frame
Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="2"
BackgroundColor="{DynamicResource process-step-upcoming}"
Padding="14,2,10,2"
HasShadow="False">
@ -251,8 +255,10 @@
<Label
Grid.Column="0"
Text="{x:Static resources:AppResources.MarkingRentalProcessCloseLockSecondStep}"
FontSize="Medium"
FontSize="17"
FontAttributes="Bold"
LineBreakMode="WordWrap"
MaxLines="2"
TextColor="White"/>
<Image
Grid.Column="1"
@ -298,7 +304,7 @@
</Frame>
<Polygon
Grid.Column="1"
Grid.Row="1"
Grid.Row="2"
Points="0,0 20,0 10,10"
IsVisible="False"
HorizontalOptions="Center">

View file

@ -40,7 +40,7 @@
<Grid
Grid.Row="0"
IsVisible="True"
RowDefinitions="50,10"
RowDefinitions="50,Auto,10"
RowSpacing="0"
ColumnDefinitions="*,*,*">
@ -58,6 +58,7 @@
<Frame
Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
BackgroundColor="{DynamicResource process-step-upcoming}"
HasShadow="False"
Padding="14,2,10,2">
@ -103,8 +104,10 @@
<Label
Grid.Column="0"
Text="{x:Static resources:AppResources.MarkingRentalProcessEndRentalFirstStep}"
FontSize="Medium"
FontSize="17"
FontAttributes="Bold"
LineBreakMode="WordWrap"
MaxLines="2"
TextColor="White">
<Label.Triggers>
<MultiTrigger TargetType="Label">
@ -206,7 +209,7 @@
</Frame>
<Polygon
Grid.Column="0"
Grid.Row="1"
Grid.Row="2"
Points="0,0 20,0 10,10"
IsVisible="False"
HorizontalOptions="Center">
@ -241,6 +244,7 @@
<Frame
Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="2"
BackgroundColor="{DynamicResource process-step-upcoming}"
HasShadow="False"
Padding="14,2,10,2">
@ -286,8 +290,10 @@
<Label
Grid.Column="0"
Text="{x:Static resources:AppResources.MarkingRentalProcessEndRentalSecondStep}"
FontSize="Medium"
FontSize="17"
FontAttributes="Bold"
LineBreakMode="WordWrap"
MaxLines="2"
TextColor="White">
<Label.Triggers>
<MultiTrigger TargetType="Label">
@ -366,7 +372,7 @@
</Frame>
<Polygon
Grid.Column="1"
Grid.Row="1"
Grid.Row="2"
Points="0,0 20,0 10,10"
IsVisible="False"
HorizontalOptions="Center">
@ -401,6 +407,7 @@
<Frame
Grid.Column="2"
Grid.Row="0"
Grid.RowSpan="2"
BackgroundColor="{DynamicResource process-step-upcoming}"
HasShadow="False"
Padding="14,2,10,2">
@ -446,8 +453,10 @@
<Label
Grid.Column="0"
Text="{x:Static resources:AppResources.MarkingRentalProcessEndRentalThirdStep}"
FontSize="Medium"
FontSize="17"
FontAttributes="Bold"
LineBreakMode="WordWrap"
MaxLines="2"
TextColor="White"/>
<Image
Grid.Column="1"
@ -493,7 +502,7 @@
</Frame>
<Polygon
Grid.Column="2"
Grid.Row="1"
Grid.Row="2"
Points="0,0 20,0 10,10"
IsVisible="False"
HorizontalOptions="Center">

View file

@ -51,7 +51,7 @@
Padding="0"
Margin="0">
<Label
Text="{x:Static resources:AppResources.ActionReturn}"
Text="{x:Static resources:AppResources.ActionEndRental}"
FontSize="Large"
TextColor="White"
HorizontalOptions="Center"

View file

@ -50,7 +50,7 @@
Padding="0"
Margin="0">
<Label
Text="{x:Static resources:AppResources.ActionClose}"
Text="{x:Static resources:AppResources.ActionCloseLock}"
FontSize="Large"
TextColor="White"
HorizontalOptions="Center"

View file

@ -63,7 +63,7 @@
<FontImageSource
Glyph="{StaticResource check}"
FontFamily="FA-S"
Size="Large"
Size="22"
Color="White"/>
</Image.Source>
</Image>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.374" android:versionCode="374">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.375" android:versionCode="375">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="33" />
<!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services -->

File diff suppressed because it is too large Load diff

View file

@ -1,104 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
#if ARENDI
using Arendi.BleLibrary;
using Arendi.BleLibrary.Adapter;
using Arendi.BleLibrary.Android;
using Arendi.BleLibrary.Local;
using Arendi.BleLibrary.Remote;
#endif
using Xamarin.Forms;
[assembly: Dependency(typeof(TINK.Droid.Services.BluetoothLock.Arendi.Central))]
namespace TINK.Droid.Services.BluetoothLock.Arendi
{
#if ARENDI
public class Central : ICentral
#else
public class Central
#endif
{
#if ARENDI
private bool disposedValue;
private static ICentral central = CentralFactory.GetCentral();
public global::Arendi.BleLibrary.Adapter.IAdapter Adapter => throw new NotImplementedException();
public BluetoothState BluetoothState => throw new NotImplementedException();
public ISecurityManager SecurityManager => throw new NotImplementedException();
public IBondManager BondManager => throw new NotImplementedException();
public IDictionary<string, string> SystemInformation => throw new NotImplementedException();
public event EventHandler<PeripheralDiscoveredEventArgs> PeripheralDiscovered;
public event EventHandler<BluetoothStateChangedEventArgs> BluetoothStateChanged;
public event EventHandler<EventArgs> SystemInformationUpdated;
public event EventHandler<FatalErrorEventArgs> FatalError;
public IPeripheral CreatePeripheralByUuid(Uuid uuid, string name = null)
=> central.CreatePeripheralByUuid(uuid, name);
public bool IsEnabled()
{
throw new NotImplementedException();
}
public void StartScan()
=> central.StartScan();
public void StartScan(string[] uuids)
{
throw new NotImplementedException();
}
public void StartScan(Uuid[] uuids)
{
throw new NotImplementedException();
}
public void StopScan()
=> central.StopScan();
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~Central()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
#endif
}
}

View file

@ -175,16 +175,16 @@
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView" Version="28.0.0.3" />
<PackageReference Include="Xamarin.Android.Support.Vector.Drawable" Version="28.0.0.3" />
<PackageReference Include="Xamarin.AndroidX.Core">
<Version>1.10.1.2</Version>
<Version>1.12.0.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.MediaRouter">
<Version>1.4.0.2</Version>
<Version>1.6.0.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.Palette">
<Version>1.0.0.19</Version>
<Version>1.0.0.21</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.RecyclerView">
<Version>1.3.1</Version>
<Version>1.3.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Auth" Version="1.7.0" />
<PackageReference Include="Xamarin.Build.Download" Version="0.11.4" />
@ -195,7 +195,7 @@
<Version>1.8.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Common">
<Version>120.3.3.1</Version>
<Version>120.3.3.3</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2612" />
<PackageReference Include="Xamarin.Forms.AppLinks">
@ -205,10 +205,10 @@
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.Forms.GoogleMaps.Bindings" Version="3.0.0" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.2" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.3" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.3" />
<PackageReference Include="Xamarin.GooglePlayServices.Base" Version="118.2.0.4" />
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="118.2.0.4" />
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.1.0.5" />
<PackageReference Include="Xamarin.GooglePlayServices.Tasks" Version="118.0.2.5" />
</ItemGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
@ -230,7 +230,6 @@
<Compile Include="Model\Device\WebView.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\BluetoothLock\Arendi\Central.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">

View file

@ -56,9 +56,9 @@
<key>CFBundleDisplayName</key>
<string>sharee.bike</string>
<key>CFBundleVersion</key>
<string>374</string>
<string>375</string>
<key>CFBundleShortVersionString</key>
<string>3.0.374</string>
<string>3.0.375</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict>

View file

@ -22,9 +22,6 @@ using TINK.Services.Permissions;
using TINK.View;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
#if ARENDI
using Arendi.BleLibrary.Local;
#endif
// Required for support of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
@ -181,13 +178,6 @@ namespace TINK
specialFolder: specialFolders,
cipher: new Cipher(),
new TINK.Services.ThemeNS.Theme(Application.Current.Resources.MergedDictionaries),
arendiCentral:
#if ARENDI
DependencyService.Get<ICentral>(),
#else
null,
#endif
postAction: (d, obj) => context.Post(d, obj),
currentVersion: appInfoService.Version,
lastVersion: lastVersion,
@ -206,12 +196,6 @@ namespace TINK
{
InitializeComponent();
#if USEFLYOUT
// Use flyout page.
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.Root.RootPage()) // Show whats new info.
: (Page)new View.Root.RootPage(); // Just start sharee- app
#else
// Check which page to show first.
var mainPage = new View.RootShell.AppShell();
var currentItem = Activator.CreateInstance(ModelRoot.StartupSettings.StartupPage.GetViewType()) as ContentPage;
@ -224,7 +208,6 @@ namespace TINK
? new View.WhatsNew.WhatsNewPage(() => MainPage = mainPage) // Show whats new info.
: (Page)mainPage; // Just start sharee- app
#endif
}
/// <summary> Concatenates all log files to a single one. </summary>

View file

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using TINK.View.Map;
using TINK.ViewModel.Map;
using Xamarin.Forms;
@ -27,11 +27,7 @@ namespace TINK
static Page GetCurrentPage()
{
#if USEFLYOUT
return (Application.Current.MainPage as FlyoutPage)?.Detail.Navigation.NavigationStack.LastOrDefault();
#else
return Shell.Current.CurrentPage;
#endif
}
}

View file

@ -1,97 +0,0 @@
#if ARENDI
using Arendi.BleLibrary;
using Arendi.BleLibrary.Adapter;
using Arendi.BleLibrary.Local;
using Arendi.BleLibrary.Remote;
#endif
using System;
using System.Collections.Generic;
using System.Text;
namespace TINK.Services.BluetoothLock.Arendi
{
#if ARENDI
public class Central : ICentral
#else
public class Central
#endif
{
#if ARENDI
private bool disposedValue;
public IAdapter Adapter => throw new NotImplementedException();
public BluetoothState BluetoothState => throw new NotImplementedException();
public ISecurityManager SecurityManager => throw new NotImplementedException();
public IBondManager BondManager => throw new NotImplementedException();
public IDictionary<string, string> SystemInformation => throw new NotImplementedException();
public event EventHandler<PeripheralDiscoveredEventArgs> PeripheralDiscovered;
public event EventHandler<BluetoothStateChangedEventArgs> BluetoothStateChanged;
public event EventHandler<EventArgs> SystemInformationUpdated;
public event EventHandler<FatalErrorEventArgs> FatalError;
public IPeripheral CreatePeripheralByUuid(Uuid uuid, string name = null)
{
throw new NotImplementedException();
}
public bool IsEnabled()
{
throw new NotImplementedException();
}
public void StartScan()
{
throw new NotImplementedException();
}
public void StartScan(string[] uuids)
{
throw new NotImplementedException();
}
public void StartScan(Uuid[] uuids)
{
throw new NotImplementedException();
}
public void StopScan()
{
throw new NotImplementedException();
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~Central()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
#endif
}
}

View file

@ -13,9 +13,7 @@
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)BackdoorMethodHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\BluetoothLock\Arendi\Central.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootShell\AppShellViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootFlyout\RootPageViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Account\AccountPage.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>%(Filename)</DependentUpon>
@ -60,13 +58,6 @@
<DependentUpon>FlyoutHeader.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml.cs">
<DependentUpon>RootPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml.cs">
<DependentUpon>RootPageFlyout.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyoutMenuItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml.cs">
<DependentUpon>AppShell.xaml</DependentUpon>
</Compile>
@ -98,7 +89,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\ViewModelResourceHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootMasterDetail\Helper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\BikesAtStation\BikesAtStationPage.xaml.cs">
<DependentUpon>BikesAtStationPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -107,10 +97,6 @@
<DependentUpon>ContactPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml.cs">
<DependentUpon>BikeInfoCarouselPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml.cs">
<DependentUpon>InfoTabbedPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -119,9 +105,6 @@
<DependentUpon>LoginPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootMasterDetail\MainPageMenuItem.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Map\MapPage.xaml.cs">
<DependentUpon>MapPage.xaml</DependentUpon>
<SubType>Code</SubType>
@ -190,12 +173,6 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml">
<SubType>Designer</SubType>
@ -250,16 +227,6 @@
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml">
<SubType>Designer</SubType>

View file

@ -2,9 +2,6 @@ using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using TINK.ViewModel.Account;
@ -13,11 +10,7 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
namespace TINK.View.Account
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class AccountPage : ContentPage, IViewService, IDetailPage
#else
public partial class AccountPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
AccountPageViewModel m_oViewModel = null;
@ -87,18 +80,9 @@ namespace TINK.View.Account
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -109,20 +93,6 @@ namespace TINK.View.Account
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.

View file

@ -31,7 +31,7 @@
Padding="0"
RowSpacing="15"
ColumnSpacing="5"
ColumnDefinitions="Auto,Auto,*"
ColumnDefinitions="Auto,*,Auto"
RowDefinitions="Auto,Auto,Auto">
<!-- Bike image -->
@ -40,6 +40,7 @@
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
HorizontalOptions="Start"
Source="{Binding DisplayedBikeImageSourceString}"
HeightRequest="60"
Aspect="AspectFit"/>
@ -50,6 +51,7 @@
Grid.Row="0"
Grid.RowSpan="2"
VerticalOptions="End"
HorizontalOptions="Start"
Current="{Binding CurrentChargeBars}"
Maximum="{Binding MaxChargeBars}"
IsVisible="{Binding IsBatteryChargeVisible}"/>
@ -68,12 +70,14 @@
<Label
Text="{Binding StateText}"
FontSize="Small"
LineBreakMode="WordWrap"
TextColor="{Binding StateColor}"/>
<!-- Rental state error info -->
<Label
Text="{Binding ErrorText}"
FontSize="Small"
LineBreakMode="WordWrap"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>

View file

@ -10,9 +10,6 @@ namespace TINK.View.BikesAtStation
using System.Threading;
using System.Threading.Tasks;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using TINK.Model;
using TINK.Services.BluetoothLock.Tdo;
@ -27,11 +24,7 @@ namespace TINK.View.BikesAtStation
using TINK.MultilingualResources;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class BikesAtStationPage : ContentPage, IViewService
#endif
{
private BikesAtStationPageViewModel m_oViewModel;
@ -39,28 +32,9 @@ namespace TINK.View.BikesAtStation
/// <summary> Initialization status to ensure initialization logic is not called multiple times. </summary>
private bool isInitializationStarted = false;
#if TRYNOTBACKSTYLE
public BikesAtStationPage()
{
InitializeComponent();
var l_oModel = App.ModelRoot;
var l_oViewModel = new BikesAtStationPageViewModel(
l_oModel.BikesAtStation,
l_oModel.ActiveUser,
l_oModel.SelectedStation,
this);
BindingContext = l_oViewModel;
BikesAtStationListView.ItemsSource = l_oViewModel;
}
#else
public BikesAtStationPage()
{
}
#endif
/// <summary>
/// Invoked when page is shown.
@ -74,11 +48,6 @@ namespace TINK.View.BikesAtStation
if (m_oViewModel != null)
{
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearingOrRefresh();
@ -122,11 +91,6 @@ namespace TINK.View.BikesAtStation
InitializeComponent();
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
@ -145,11 +109,6 @@ namespace TINK.View.BikesAtStation
// View model might be null.
await m_oViewModel?.OnDisappearing();
}
#if BACKSTYLE
if (m_oNavigation!= null)
m_oNavigation.IsGestureEnabled = true; // Enables master- detail menu navigation again when page is unloaded.
#endif
}
/// <summary>
@ -199,17 +158,9 @@ namespace TINK.View.BikesAtStation
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
/// <summary> Creates and a page an shows it.</summary>
/// <remarks> When user is not logged in navigation to Login page is supported.</remarks>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
@ -228,22 +179,6 @@ namespace TINK.View.BikesAtStation
throw new NotImplementedException();
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#else

View file

@ -15,12 +15,7 @@ using TINK.Model;
namespace TINK.View.Contact
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class ContactPage : ContentPage, IViewService, IDetailPage
#else
public partial class ContactPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify view model if page appears. </summary>
private ContactPageViewModel ViewModel { get; set; }
@ -80,14 +75,9 @@ namespace TINK.View.Contact
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string title = null)
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -106,19 +96,12 @@ namespace TINK.View.Contact
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -127,13 +110,5 @@ namespace TINK.View.Contact
#else
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail { set; private get; }
#endif
}
}

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -13,11 +10,7 @@ namespace TINK.View.Contact
using TINK.ViewModel.Contact;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SelectStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class SelectStationPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
@ -72,18 +65,9 @@ namespace TINK.View.Contact
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="type">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
@ -98,19 +82,12 @@ namespace TINK.View.Contact
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -120,11 +97,6 @@ namespace TINK.View.Contact
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
@ -136,9 +108,6 @@ namespace TINK.View.Contact
{
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
#if TRYNOTBACKSTYLE
SelectStationPageViewModel = new SelectStationPageViewModel();
#else
SelectStationPageViewModel = new SelectStationPageViewModel(
App.ModelRoot,
App.PermissionsService,
@ -147,7 +116,6 @@ namespace TINK.View.Contact
(mapspan) => MyMap.MoveToRegion(mapspan),
this,
Navigation);
#endif
}
catch (Exception exception)
{
@ -159,10 +127,6 @@ namespace TINK.View.Contact
try
{
BindingContext = SelectStationPageViewModel;
#if USEFLYOUT
SelectStationPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{

View file

@ -156,14 +156,9 @@ namespace TINK.View.FindBike
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>

View file

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Info.BikeInfo.BikeInfoCarouselPage">
<CarouselPage.ItemTemplate>
<DataTemplate>
<ContentPage>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,40,0,0" />
</OnPlatform>
</ContentPage.Padding>
<ScrollView Orientation="Vertical">
<StackLayout>
<Label
Text="{Binding Title}"
FontSize="Medium"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
VerticalOptions="EndAndExpand"
VerticalTextAlignment="End"/>
<Image
IsVisible="{Binding IsImageVisble}"
Source="{Binding Image}"
Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
<Label
Text="{Binding DescriptionText}"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
VerticalOptions="StartAndExpand"
VerticalTextAlignment="Start"/>
<Button
Text="Schließen"
IsVisible="{Binding IsCloseVisible}"
Command="{Binding OnCloseRequest}"
VerticalOptions="End"/>
<ProgressBar
VerticalOptions="End"
Progress="{Binding ProgressValue}"/>
</StackLayout>
</ScrollView>
</ContentPage>
</DataTemplate>
</CarouselPage.ItemTemplate>
</CarouselPage>

View file

@ -1,129 +0,0 @@
using System;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using TINK.ViewModel.Info.BikeInfo;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Info.BikeInfo
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class BikeInfoCarouselPage : CarouselPage, IViewService, IDetailPage
#else
public partial class BikeInfoCarouselPage : CarouselPage, IViewService
#endif
{
public BikeInfoCarouselPage()
{
InitializeComponent();
ItemsSource = new BikeInfoViewModel(
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.ResourcePrefix}Images.{resourceName}"),
this).CarouselItems;
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strCancel">Type of buttons.</param>
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strAccept">Text of accept button.</param>
/// <param name="p_strCancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
{
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
}
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
{
throw new NotSupportedException();
}
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync()
{
throw new NotSupportedException();
}
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushAsync(ViewTypes p_oTypeOfPage)
{
throw new NotImplementedException();
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
}
}

View file

@ -2,9 +2,6 @@ using System;
using System.Threading.Tasks;
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -12,11 +9,7 @@ using Xamarin.Forms.Xaml;
namespace TINK.View.Login
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class LoginPage : ContentPage, IViewService, IDetailPage
#else
public partial class LoginPage : ContentPage, IViewService
#endif
{
/// <summary> Reference to view model. </summary>
LoginPageViewModel m_oViewModel = null;
@ -27,16 +20,12 @@ namespace TINK.View.Login
InitializeComponent();
var l_oModel = App.ModelRoot;
#if !BACKSTYLE
m_oViewModel = new LoginPageViewModel(
l_oModel,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
this);
BindingContext = m_oViewModel;
#else
LoginPageView.BindingContext = new LoginPageViewModel(l_oModel.ActiveUser, this, Navigation);
#endif
}
/// <summary>
@ -70,18 +59,9 @@ namespace TINK.View.Login
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, !string.IsNullOrEmpty(details) ? $"{message}\r\nDetails:\r\n{details}" : $"{message}", accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
@ -103,21 +83,6 @@ namespace TINK.View.Login
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else

View file

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -13,11 +10,7 @@ namespace TINK.View.Map
using TINK.ViewModel.Map;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class MapPage : ContentPage, IViewService, IDetailPage
#else
public partial class MapPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private MapPageViewModel MapPageViewModel { get; set; }
@ -75,18 +68,9 @@ namespace TINK.View.Map
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
@ -101,20 +85,12 @@ namespace TINK.View.Map
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
@ -124,11 +100,6 @@ namespace TINK.View.Map
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBatteryMutable battery = null) => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
@ -144,11 +115,7 @@ namespace TINK.View.Map
{
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
#if TRYNOTBACKSTYLE
MapPageViewModel = new MapPageViewModel();
#else
MapPageViewModel = CreateMapPageViewModel();
#endif
}
catch (Exception exception)
{
@ -161,9 +128,6 @@ namespace TINK.View.Map
{
BindingContext = MapPageViewModel;
#if USEFLYOUT
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{

View file

@ -67,14 +67,9 @@ namespace TINK.View.MiniSurvey
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>

View file

@ -2,9 +2,6 @@ using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
@ -153,14 +150,9 @@ namespace TINK.View.MyBikes
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>

View file

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Root.RootPage"
xmlns:pages="clr-namespace:TINK.View.Root"
xmlns:mappage="clr-namespace:TINK.View.Map">
<FlyoutPage.Flyout>
<pages:RootPageFlyout x:Name="FlyoutPage" />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<mappage:MapPage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>

View file

@ -1,95 +0,0 @@
using System;
using TINK.Model.Stations;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
/// <summary>
/// Manages creation of detail pages if a flyout page menu entry is selected.
/// Exposes flyout page style navigation which is used by detail pages.
/// </summary>
/// <remarks>
/// Examples of use cases when detail pages do navigation:
// - switch to map page after successfully logging in/ logging out
// - switch to login page form bikes at station page if not yet logged in
/// </remarks>
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class RootPage : FlyoutPage, INavigationMasterDetail
#else
public partial class RootPage : FlyoutPage
#endif
{
public RootPage()
{
InitializeComponent();
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
// Any type of split behavior conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
var navigationPage = Detail as NavigationPage;
if (navigationPage == null)
{
return;
}
#if USEFLYOUT
var detailPage = navigationPage.RootPage as IDetailPage;
if (detailPage == null)
{
return;
}
detailPage.NavigationMasterDetail = this;
#endif
}
/// <summary>
/// Is called if a flyout page menu entry is selected.
/// Creates a new page.
/// </summary>
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (!(e.SelectedItem is RootPageFlyoutMenuItem item))
{
// Unexpected argument detected.
return;
}
// Set selected station to new
App.ModelRoot.SelectedStation = new TINK.Model.Stations.StationNS.NullStation();
ShowPage(item.TargetType, item.Title);
IsPresented = false;
FlyoutPage.ListView.SelectedItem = null;
}
/// <summary>
/// Shows a detail page.
/// </summary>
/// <param name="typeOfPage">Type of page to show.</param>
/// <param name="title">Title of page.</param>
public void ShowPage(Type typeOfPage, string title)
{
var page = (Page)Activator.CreateInstance(typeOfPage);
page.Title = title;
#if USEFLYOUT
if (page is IDetailPage detailPage)
{
// Detail page needs reference to perform navigation.
// Examples see above in xdoc of class.
detailPage.NavigationMasterDetail = this;
}
#endif
Detail = new NavigationPage(page);
}
}
}

View file

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Root.RootPageFlyout"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:local="clr-namespace:TINK.View"
IconImageSource="menu"
Title="sharee.bike">
<StackLayout>
<ListView x:Name="MenuItemsListView"
SeparatorVisibility="None"
HasUnevenRows="true"
local:ListViewAttachedBehavior.Command="{Binding MenuItemSelected}"
ItemsSource="{Binding MenuItems}">
<ListView.Header>
<Grid BackgroundColor="{DynamicResource Key=primary-back-title-color}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="80"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Label
Grid.Column="1"
Grid.Row="2"
Text="{Binding MasterDetailMenuTitlte}"
Style="{DynamicResource SubtitleStyle}"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image>
<Image.Source>
<FontImageSource Glyph="{Binding GlyphCode}" Color="Black" FontFamily="FA-S"/>
</Image.Source>
</Image>
<Label
Grid.Column="1"
Margin="10, 0, 0, 0"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
FontSize="18"
Text="{Binding Title}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>

View file

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using TINK.Model;
using TINK.Services;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.View.Themes;
using TINK.ViewModel.Root;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPageFlyout : ContentPage
{
public ListView ListView;
public RootPageFlyout()
{
InitializeComponent();
BindingContext = new RootPageFlyoutViewModel();
ListView = MenuItemsListView;
}
}
}

View file

@ -1,20 +0,0 @@
using System;
namespace TINK.View.Root
{
public class RootPageFlyoutMenuItem
{
public RootPageFlyoutMenuItem()
{
TargetType = typeof(RootPageFlyoutMenuItem);
}
public int Id { get; set; }
public string GlyphCode { get; set; }
public string Title { get; set; }
public Type TargetType { get; set; }
}
}

View file

@ -1,42 +0,0 @@
using System;
using TINK.View.Map;
using TINK.ViewModel.MasterDetail;
namespace TINK.View
{
public class MainPageMenuItem
{
public MainPageMenuItem()
{
TargetType = typeof(MapPage);
}
public MainPageMenuItem(
int p_iId,
Type p_oTypeOfPage,
string p_strTitle = null)
{
TargetType = p_oTypeOfPage;
Id = p_iId;
Title = p_strTitle ?? Helper.GetCaption(p_oTypeOfPage);
}
public int Id
{
get;
private set;
}
public string Title
{
get;
private set;
}
public Type TargetType
{
get;
private set;
}
}
}

View file

@ -2,9 +2,6 @@ using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using Xamarin.CommunityToolkit.Extensions;
@ -13,11 +10,7 @@ using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
namespace TINK.View.Settings
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SettingsPage : ContentPage, IViewService, IDetailPage
#else
public partial class SettingsPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
SettingsPageViewModel m_oViewModel = null;
@ -89,18 +82,9 @@ namespace TINK.View.Settings
public new async Task<string> DisplayActionSheet(String p_strTitle, String p_strCancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(p_strTitle, p_strCancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
@ -111,19 +95,6 @@ namespace TINK.View.Settings
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.

View file

@ -4,7 +4,6 @@ using TINK.View.Contact;
using TINK.View.CopriWebView;
using TINK.View.FindBike;
using TINK.View.Info;
using TINK.View.Info.BikeInfo;
using TINK.View.Login;
using TINK.View.Map;
using TINK.View.MiniSurvey;
@ -34,9 +33,6 @@ namespace TINK.View
case ViewTypes.PasswordForgottenPage:
return typeof(PasswordForgottenPage);
case ViewTypes.BikeInfoCarouselPage:
return typeof(BikeInfoCarouselPage);
case ViewTypes.MyBikesPage:
return typeof(MyBikesPage);

View file

@ -65,14 +65,9 @@ namespace TINK.View.WhatsNew.Agb
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
=> throw new NotImplementedException();
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();

View file

@ -68,14 +68,10 @@ namespace TINK.View.WhatsNew
await Navigation.PushModalAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();

View file

@ -1,198 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using TINK.Services.CopriApi.ServerUris;
using TINK.View;
using TINK.View.Account;
using TINK.View.Contact;
using TINK.View.Info;
using TINK.View.Login;
using TINK.View.Map;
using TINK.View.FindBike;
using TINK.View.MyBikes;
using TINK.View.Root;
using TINK.View.Settings;
using Xamarin.Forms;
using TINK.ViewModel.MasterDetail;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.Services;
using TINK.View.Themes;
namespace TINK.ViewModel.Root
{
/// <summary>
/// View model for flyout menu entries. Respositility
/// - populates entries depending on app state on showing menu
/// - updates menu denpending on app state change, i.e. user logs in/ out.
/// </summary>
public class RootPageFlyoutViewModel : INotifyPropertyChanged
{
/// <summary>
/// Dictionary to manage collection of menu items.
/// </summary>
private Dictionary<Type, int> m_oEntryDictionary;
public event PropertyChangedEventHandler PropertyChanged;
/// <summary> Updates menu entries depending on state. </summary>
private void UpdateMenuEntries()
{
for (int l_iIndex = MenuItems.Count - 1; l_iIndex >= 0; l_iIndex--)
{
MenuItems.Clear();
m_oEntryDictionary.Clear();
}
CheckAddItem(typeof(MapPage));
if (App.ModelRoot.ActiveUser.IsLoggedIn)
{
CheckAddItem(typeof(MyBikesPage));
CheckAddItem(typeof(FindBikePage));
CheckAddItem(typeof(AccountPage));
}
else
{
CheckAddItem(typeof(LoginPage));
}
if (App.ModelRoot.Uris.ActiveUri.Host.GetIsCopri()
|| App.ModelRoot.ActiveUser.IsLoggedIn)
{
CheckAddItem(typeof(SettingsPage));
}
CheckAddItem(typeof(FeesAndBikesPage)); // Fees and bikes
CheckAddItem(typeof(ContactPage)); // Feedback and contact
CheckAddItem(typeof(InfoPage)); // About sharee.bike
}
/// <summary>Adds a menu item to master detail menu.</summary>
/// <param name="p_oType">Type decribing entry to be added.</param>
private void CheckAddItem(Type p_oType)
{
if (m_oEntryDictionary.ContainsKey(p_oType))
{
// Nothing to do because has already been added.
return;
}
m_oEntryDictionary.Add(
p_oType,
m_oEntryDictionary.Count);
MenuItems.Add(new RootPageFlyoutMenuItem
{
TargetType = p_oType,
GlyphCode = Helper.GetGlyphCode(p_oType),
Title = Helper.GetCaption(p_oType),
Id = m_oEntryDictionary[p_oType]
});
}
/// <summary> Removes a page from menu.</summary>
/// <param name="p_oType"></param>
private void RemoveItem(Type p_oType)
{
if (!m_oEntryDictionary.ContainsKey(p_oType))
{
// Nothing to do because item was never added/ already removed.
return;
}
MenuItems.Remove(MenuItems[m_oEntryDictionary[p_oType]]);
m_oEntryDictionary.Remove(p_oType);
}
public RootPageFlyoutViewModel()
{
MenuItems = new ObservableCollection<RootPageFlyoutMenuItem>();
m_oEntryDictionary = new Dictionary<Type, int>();
// Update menu entries on login/ logout actions.
App.ModelRoot.ActiveUser.StateChanged += (sender, eventargs) => OnUpdateRequired();
// Update flyout view model whenever theme is switched.
App.ModelRoot.Themes.PropertyChanged += (sender, eventargs) =>
{
if (!(sender is ServicesContainerMutableT<object> themes))
return;
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(themes.Active);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MasterDetailMenuTitlte)));
};
MasterDetailMenuTitlte = GetMasterDetailMenuTitle(App.ModelRoot.Themes.Active);
UpdateMenuEntries();
}
/// <summary>
/// Gets the flyout title from theme name
/// </summary>
/// <param name="theme">Name of theme.</param>
/// <returns>Flyout title.</returns>
private string GetMasterDetailMenuTitle(object theme)
{
if (!(theme is ITheme active))
return "sharee.bike";
return !string.IsNullOrEmpty(active.OperatorInfo) ? $"{active.OperatorInfo}" : "sharee.bike";
}
/// <summary>
/// Holds the title of the fylout page.
/// </summary>
public string MasterDetailMenuTitlte { get; private set; }
/// <summary>
/// Provides collection of menu items for master page.
/// </summary>
public ObservableCollection<RootPageFlyoutMenuItem> MenuItems
{
get; private set;
}
/// <summary>
/// Gets or sets the selected item.
/// </summary>
public MainPageMenuItem SelectedMenuItem
{
get;
set;
}
/// <summary>
/// Command object which is invoked from view when an item is selected.
/// </summary>
public Command MenuItemSelected
{
get
{
return new Command(OnUpdateRequired);
}
}
/// <summary> Manges updates required due to selection of a menu or login events.</summary>
public void OnUpdateRequired()
{
UpdateMenuEntries();
if (SelectedMenuItem == null)
{
// Nothing to do if no menu entry is selected.
return;
}
}
}
}

View file

@ -1,115 +0,0 @@
using System;
using TINK.MultilingualResources;
using TINK.View.Account;
using TINK.View.Contact;
using TINK.View.FindBike;
using TINK.View.Info;
using TINK.View.Login;
using TINK.View.Map;
using TINK.View.MyBikes;
using TINK.View.Settings;
using TINK.ViewModel.Info;
namespace TINK.ViewModel.MasterDetail
{
public static class Helper
{
/// <summary>
/// Gets a description for a map page used as menu item entry and caption.
/// </summary>
/// <param name="type">Type of page to get caption for.</param>
/// <returns></returns>
public static string GetCaption(Type type)
{
if (type == typeof(MapPage)) // Bikes sites
{
return AppResources.MarkingMapPage;
}
else if (type == typeof(FindBikePage)) // Find Bike
{
return AppResources.MarkingFindBike;
}
else if (type == typeof(MyBikesPage)) // My Bikes
{
return AppResources.MarkingMyBikes;
}
else if (type == typeof(AccountPage)) // Account
{
return AppResources.MarkingAccount;
}
else if (type == typeof(LoginPage)) // Login
{
return AppResources.MarkingLogin;
}
else if (type == typeof(SettingsPage)) // Settings
{
return AppResources.MarkingSettings;
}
else if (type == typeof(FeesAndBikesPage))
{
return AppResources.MarkingFeesAndBikes;
}
else if (type == typeof(ContactPage))
{
return AppResources.MarkingFeedbackAndContact;
}
else if (type == typeof(InfoPage))
{
return AppResources.MarkingAbout;
}
else
{
return type.Name;
}
}
/// <summary>
/// Gets a description for a map page used as menu item entry and caption.
/// </summary>
/// <param name="type">Type of page to get caption for.</param>
/// <returns></returns>
public static string GetGlyphCode(Type type)
{
if (type == typeof(MapPage)) // Bikes sites
{
return "\uf5a0";
}
else if (type == typeof(FindBikePage)) // My Bikes
{
return "\uf002";
}
else if (type == typeof(MyBikesPage)) // My Bikes
{
return "\uf206";
}
else if (type == typeof(AccountPage)) // Account
{
return "\uf007";
}
else if (type == typeof(LoginPage)) // Login
{
return "\uf2f6";
}
else if (type == typeof(SettingsPage)) // Settings
{
return "\uf013";
}
else if (type == typeof(FeesAndBikesPage))
{
return "\uf7d9";
}
else if (type == typeof(ContactPage))
{
return "\uf095";
}
else if (type == typeof(InfoPage))
{
return "\uf05a";
}
else
{
return type.Name;
}
}
}
}

View file

@ -104,7 +104,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <summary>
/// Converts the instance to text.
/// </summary>
public new string ToString()
public override string ToString()
{
return $"Id={Bike.Id}{(Bike.WheelType != null ? $", wheel(s)={Bike.WheelType}" : string.Empty)}{(Bike.TypeOfBike != null ? $"type={Bike.TypeOfBike}" : "")}, state={State}, location={(!string.IsNullOrEmpty(StationId) ? $"Station {StationId}" : "On the road")}, is demo={IsDemo}.";
}

View file

@ -149,7 +149,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <summary>
/// Converts the instance to text.
/// </summary>
public new string ToString()
public override string ToString()
{
return $"Id={Id}{(WheelType != null ? $", wheel(s)={WheelType}" : string.Empty)}{(TypeOfBike != null ? $", type={TypeOfBike}" : "")}, demo={IsDemo}, state={State.ToString()}, location={(!string.IsNullOrEmpty(StationId) ? $"Station {StationId}" : "On the road")}.";
}

View file

@ -39,7 +39,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary>
Uri OperatorUri { get; }
/// <summary> Holds description about the tarif. </summary>
/// <summary> Holds description about the tariff. </summary>
RentalDescription TariffDescription { get; }
/// <summary>

View file

@ -107,7 +107,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BikeNS
}
/// <summary> Converts the instance to text.</summary>
public new string ToString()
public override string ToString()
{
return WheelType == null || TypeOfBike == null
? $"Id={Id}{(!string.IsNullOrEmpty(Description) ? $", {Description}" : "")}"

View file

@ -110,9 +110,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
LockService,
listener: listener);
public new string ToString()
public override string ToString()
{
return $"Id={Id}{(TypeOfBike != null ? $";type={TypeOfBike}" : "")};state={State.ToString()}";
return $"Id={Id}{(TypeOfBike != null ? $";type={TypeOfBike}" : "")};state={State.ToString()};Lock id={LockInfo.Id}";
}
}
}

View file

@ -10,6 +10,7 @@ using TINK.Services.BluetoothLock;
using TINK.Services.BluetoothLock.Exception;
using TINK.Services.BluetoothLock.Tdo;
using TINK.Services.Geolocation;
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
{
@ -91,9 +92,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
{
listener.ReportStep(step);
}
catch (Exception ex)
catch (Exception exception)
{
Log.ForContext<T>().Error("An exception {exception} was thrown invoking step- action for set {step} ", ex, step);
Log.ForContext<T>().Error("An exception {@exception} was thrown invoking step-action for step {step} ", exception, step);
}
}
@ -107,9 +108,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
{
await listener.ReportStateAsync(state, message);
}
catch (Exception ex)
catch (Exception exception)
{
Log.ForContext<T>().Error("An exception {exception} was thrown invoking state- action for set {state} ", ex, state);
Log.ForContext<T>().Error("An exception {@exception} was thrown invoking state-action for state {state} ", exception, state);
}
}
@ -118,21 +119,21 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
{
// Step: Wait until getting geolocation has completed.
InvokeCurrentStep(Step.WaitStopPollingQueryLocation);
Log.ForContext<T>().Debug($"Waiting on steps {Step.StartingQueryingLocation} and {Step.StartStopingPolling} to finish...");
Log.ForContext<T>().Information($"Waiting on steps {Step.StartingQueryingLocation} and {Step.StartStopingPolling} to finish...");
try
{
await Task.WhenAll(new List<Task> { locationTask, stopPollingTask ?? Task.CompletedTask });
}
catch (Exception ex)
catch (Exception exception)
{
// No location information available.
Log.ForContext<T>().Information("Canceling query location/ wait for polling task to finish failed. {Exception}", ex);
await InvokeCurrentStateAsync(State.WaitGeolocationException, ex.Message);
Log.ForContext<T>().Information("Canceling query location/ wait for polling task to finish failed. {@exception}", exception);
await InvokeCurrentStateAsync(State.WaitGeolocationException, exception.Message);
InvokeCurrentStep(Step.QueryLocationTerminated);
return null;
}
Log.ForContext<T>().Debug($"Steps {Step.StartingQueryingLocation} and {Step.StartStopingPolling} finished.");
Log.ForContext<T>().Information($"Steps {Step.StartingQueryingLocation} and {Step.StartStopingPolling} finished.");
InvokeCurrentStep(Step.QueryLocationTerminated);
return locationTask.Result;
}
@ -155,21 +156,23 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
Age = timeStamp.Subtract(location.Timestamp.DateTime),
}.Build()
: null);
Log.ForContext<T>().Information("Backend updated for bike {bikeId} successfully.", bike.Id);
}
catch (Exception exception)
{
Log.ForContext<ReservedOpen>().Information("Updating backend for bike {bikeId} failed.", bike.Id);
//BikesViewModel.RentalProcess.Result = CurrentStepStatus.Failed;
if (exception is WebConnectFailureException)
{
// Copri server is not reachable.
Log.ForContext<T>().Information("User locked bike {bike} in order to pause ride but updating failed (Copri server not reachable).", bike);
Log.ForContext<T>().Debug("Copri server not reachable.");
await InvokeCurrentStateAsync(State.WebConnectFailed, exception.Message);
return;
}
else if (exception is ResponseException copriException)
{
// Copri server is not reachable.
Log.ForContext<T>().Information("User locked bike {bike} in order to pause ride but updating failed. Message: {Message} Details: {Details}", bike, copriException.Message, copriException.Response);
Log.ForContext<T>().Debug("Message: {Message} Details: {Details}", copriException.Message, copriException.Response);
await InvokeCurrentStateAsync(State.ResponseIsInvalid, exception.Message);
return;
}
@ -192,48 +195,49 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
try
{
currentLocationTask = geolocation.GetAsync(ctsLocation.Token, timeStampNow);
Log.ForContext<T>().Information("Starting query location successful.");
}
catch (Exception ex)
catch (Exception exception)
{
// No location information available.
Log.ForContext<T>().Information("Starting query location failed. {Exception}", bike, ex);
await InvokeCurrentStateAsync(State.StartGeolocationException, ex.Message);
Log.ForContext<T>().Information("Starting query location failed. {@exception}", exception);
await InvokeCurrentStateAsync(State.StartGeolocationException, exception.Message);
}
//// Step: Close lock.
IGeolocation currentLocation;
Log.ForContext<T>().Debug($"Starting step {Step.ClosingLock}...");
Log.ForContext<T>().Information($"Starting step {Step.ClosingLock}...");
InvokeCurrentStep(Step.ClosingLock);
LockitLockingState? lockingState;
try
{
lockingState = await lockService[bike.LockInfo.Id].CloseAsync();
Log.ForContext<T>().Information("Lock of bike {bikeId} closed successfully.", bike.Id);
}
catch (Exception exception)
{
Log.ForContext<T>().Information("Lock of bike {bikeId} can not be closed.", bike.Id);
if (exception is OutOfReachException)
{
Log.ForContext<T>().Debug("Lock can not be closed. {Exception}", exception);
Log.ForContext<T>().Debug("Lock is out of reach");
await InvokeCurrentStateAsync(State.OutOfReachError, exception.Message);
}
else if (exception is CouldntCloseMovingException)
{
Log.ForContext<T>().Debug("Lock can not be closed. Lock is out of reach. {Exception}", exception);
Log.ForContext<T>().Debug("Lock is moving.");
await InvokeCurrentStateAsync(State.CouldntCloseMovingError, exception.Message);
}
else if (exception is CouldntCloseBoltBlockedException)
{
Log.ForContext<T>().Debug("Lock can not be closed. Lock is out of reach. {Exception}", exception);
Log.ForContext<T>().Debug("Bold is blocked.}");
await InvokeCurrentStateAsync(State.CouldntCloseBoltBlockedError, exception.Message);
}
else
{
Log.ForContext<T>().Debug("Lock can not be closed. Lock is out of reach. {Exception}", exception);
Log.ForContext<T>().Debug("{@exception}", exception);
await InvokeCurrentStateAsync(State.GeneralCloseError, exception.Message);
}
Log.ForContext<T>().Error("Lock can not be closed. {Exception}", exception);
// Signal cts to cancel getting geolocation.
ctsLocation.Cancel();

View file

@ -75,9 +75,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
try
{
listener.ReportStep(step);
} catch (Exception ex)
} catch (Exception exception)
{
Log.ForContext<T>().Error("An exception {exception} was thrown invoking step- action for set {step} ", ex, step);
Log.ForContext<T>().Error("An exception {@exception} was thrown invoking step-action for step {step} ", exception, step);
}
}
@ -91,9 +91,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
{
await listener.ReportStateAsync(state, message);
}
catch (Exception ex)
catch (Exception exception)
{
Log.ForContext<T>().Error("An exception {exception} was thrown invoking state- action for set {state} ", ex, state);
Log.ForContext<T>().Error("An exception {@exception} was thrown invoking state-action for state {state} ", exception, state);
}
}
@ -121,8 +121,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
if (deviceState != DeviceState.Connected)
{
// Geolocation can not be queried because bike is not around.
Log.ForContext<T>().Information("User selected booked bike {bike} but returning failed. There is no geolocation information available.", bike);
Log.ForContext<T>().Information("User selected booked bike {bikeId} but returning failed. There is no geolocation information available.", bike.Id);
await InvokeCurrentStateAsync(State.DisconnetedNoLocationError, "");
//// Step: Disconnect lock.
@ -130,11 +129,11 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
try
{
bike.LockInfo.State = await lockService.DisconnectAsync(bike.LockInfo.Id, bike.LockInfo.Guid);
Log.ForContext<T>().Information("Lock from bike {bikeId} disconnected successfully.", bike.Id);
}
catch (Exception exception)
{
Log.ForContext<T>().Error("Lock can not be disconnected. {Exception}", exception);
Log.ForContext<T>().Information("Lock from bike {bikeId} can not be disconnected. {@exception}", bike.Id, exception);
await InvokeCurrentStateAsync(State.DisconnectError, exception.Message);
}
@ -148,20 +147,19 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command
try
{
closingLockLocation = await geolocation.GetAsync(ctsLocation.Token, DateTime.Now);
Log.ForContext<T>().Information("Query location of lock from bike {bikeId} successful.");
}
catch (Exception ex)
catch (Exception exception)
{
// No location information available.
Log.ForContext<T>().Information("Returning closed bike {Bike} is not possible. Geolocation query failed. {Exception}", bike, ex);
await InvokeCurrentStateAsync(State.QueryLocationFailed, ex.Message);
Log.ForContext<T>().Information("Geolocation query failed. {@exception}", exception);
await InvokeCurrentStateAsync(State.QueryLocationFailed, exception.Message);
throw;
}
await InvokeCurrentStateAsync(State.QueryLocationSucceeded, string.Empty);
// Update last lock state time
// save geolocation data for sending to backend
var currentLocationDto = closingLockLocation != null
? new LocationDto.Builder

View file

@ -185,7 +185,7 @@ namespace TINK.Model.Connector
}
/// <summary> Updates COPRI lock state for a booked bike. </summary>
/// <summary> Updates COPRI lock state for a booked or reserved bike. </summary>
/// <param name="bike">Bike to update locking state for.</param>
/// <param name="location">Location of the bike.</param>
/// <returns>Response on updating locking state.</returns>
@ -198,7 +198,7 @@ namespace TINK.Model.Connector
throw new ArgumentNullException("Can not update locking state of bike. No bike object available.");
}
if (bike.State.Value != State.InUseStateEnum.Booked)
if (bike.State.Value != State.InUseStateEnum.Booked && bike.State.Value != State.InUseStateEnum.Reserved)
{
throw new ArgumentNullException($"Can not update locking state of bike. Unexpected booking state {bike.State} detected.");
}

View file

@ -11,12 +11,12 @@ namespace TINK.Model.Connector
public class ConnectorCache : IConnector
{
/// <summary>Constructs a copri connector object to connect to cache.</summary>
/// <remarks>Used for offline szenario to ensure responsiveness of app by preventing hopeless tries to communicate with COPRI. </remarks>
/// <remarks>Used for offline scenario to ensure responsiveness of app by preventing hopeless tries to communicate with COPRI. </remarks>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
/// <param name="sessionCookie"> Holds the session cookie.</param>
/// <param name="mail">Mail of user.</param>
/// <param name="smartDevice">Holds info about smart device.</param>
/// <param name="server"> Is null in production and migh be a mock in testing context.</param>
/// <param name="server"> Is null in production and might be a mock in testing context.</param>
public ConnectorCache(
AppContextInfo appContextInfo,
string uiIsoLangugageName,
@ -36,10 +36,10 @@ namespace TINK.Model.Connector
mail);
}
/// <summary> Object for queriying stations and bikes.</summary>
/// <summary> Object for querying stations and bikes.</summary>
public ICommand Command { get; private set; }
/// <summary> Object for queriying stations and bikes.</summary>
/// <summary> Object for querying stations and bikes.</summary>
public IQuery Query { get; private set; }
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>

View file

@ -64,9 +64,10 @@ namespace TINK.Model.Connector
}
/// <summary> Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in. </summary>
public async Task<Result<BikeCollection>> GetBikesAsync()
/// <param name="operatorUri">Uri of the operator host to get bikes from or null if bikes have to be gotten form primary host.</param>
public async Task<Result<BikeCollection>> GetBikesAsync(Uri operatorUri = null)
{
var result = await m_oInnerQuery.GetBikesAsync();
var result = await m_oInnerQuery.GetBikesAsync(operatorUri);
return new Result<BikeCollection>(
result.Source,
new BikeCollection(DoFilter(result.Response, Filter)),
@ -129,6 +130,7 @@ namespace TINK.Model.Connector
station.Group,
station.Position,
station.StationName,
station.OperatorUri,
station.OperatorData,
new BikeGroupCol(station.BikeGroups
.Where(group => filter.DoFilter(new List<string> { group.Group }).Count() > 0))) as IStation)

View file

@ -1,11 +1,11 @@
namespace TINK.Model.Connector
namespace TINK.Model.Connector
{
public interface IConnector
{
/// <summary> Object for queriying stations and bikes.</summary>
/// <summary> Object for querying stations and bikes.</summary>
ICommand Command { get; }
/// <summary> Object for queriying stations and bikes.</summary>
/// <summary> Object for querying stations and bikes.</summary>
IQuery Query { get; }
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>

View file

@ -56,9 +56,10 @@ namespace TINK.Model.Connector
}
/// <summary> Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in. </summary>
public async Task<Result<BikeCollection>> GetBikesAsync()
/// <param name="operatorUri">Uri of the operator host to get bikes from or null if bikes have to be gotten form primary host.</param>
public async Task<Result<BikeCollection>> GetBikesAsync(Uri operatorUri = null)
{
var result = await m_oInnerQuery.GetBikesAsync();
var result = await m_oInnerQuery.GetBikesAsync(operatorUri);
return new Result<BikeCollection>(
result.Source,
new BikeCollection(result.Response.ToDictionary(x => x.Id)),

View file

@ -71,14 +71,15 @@ namespace TINK.Model.Connector
}
/// <summary> Gets bikes available. </summary>
/// <param name="operatorUri">Uri of the operator host to get bikes from or null if bikes have to be gotten form primary host.</param>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
public async Task<Result<BikeCollection>> GetBikesAsync(Uri operatorUri = null)
{
var result = await server.GetBikesAvailable();
var result = await server.GetBikesAvailable(operatorUri: operatorUri);
if (result.Source != typeof(CopriCallsMonkeyStore))
{
server.AddToCache(result);
server.AddToCache(result, operatorUri);
}

View file

@ -127,21 +127,24 @@ namespace TINK.Model.Connector
}
/// <summary> Gets bikes available and bikes occupied. </summary>
/// <param name="operatorUri">Uri of the operator host to get bikes from or null if bikes have to be gotten form primary host.</param>
/// <returns>Collection of bikes.</returns>
public async Task<Result<BikeCollection>> GetBikesAsync()
public async Task<Result<BikeCollection>> GetBikesAsync(Uri operatorUri = null)
{
var bikesAvailableResponse = await Server.GetBikesAvailable();
var bikesAvailableResponse = await Server.GetBikesAvailable(operatorUri: operatorUri);
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesAvailableResponse.Exception != null)
{
// Bikes available were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies.
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
// Bikes were read from cache.
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and bikes occupied from cache invoking one single call.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
operatorUri?.AbsoluteUri == null ?
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values // Get bikes occupied from cache as well to avoid inconsistencies.
: bikesAvailableResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
@ -149,7 +152,27 @@ namespace TINK.Model.Connector
bikesAvailableResponse.Exception);
}
var bikesOccupiedResponse = await Server.GetBikesOccupied();
if (operatorUri?.AbsoluteUri != null)
{
// Both types bikes could read from copri successfully => update cache
Server.AddToCache(bikesAvailableResponse, operatorUri);
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and occupied read successfully from server invoking one single request.");
return new Result<BikeCollection>(
bikesAvailableResponse.Source,
BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values,
bikesAvailableResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Copri),
bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception != null ? new AggregateException(new[] { bikesAvailableResponse.Exception }) : null);
}
/// Legacy implementation: GetBikesOccupied are not returned in <see cref="ICachedCopriServer.GetBikesAvailable"/> call.
/// A separate call <see cref="ICachedCopriServer.GetBikesOccupied"/> is required to retrieve all bikes.
var bikesOccupiedResponse = await Server.GetBikesOccupied(); /* Only query bikes occupied if operator uri is unknown. */
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|| bikesOccupiedResponse.Exception != null)
{
@ -158,7 +181,7 @@ namespace TINK.Model.Connector
return new Result<BikeCollection>(
bikesOccupiedResponse.Source,
BikeCollectionFactory.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
(await Server.GetBikesAvailable(true, operatorUri)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail,
DateTimeProvider,
@ -168,7 +191,7 @@ namespace TINK.Model.Connector
}
// Both types bikes could read from copri => update cache
Server.AddToCache(bikesAvailableResponse);
Server.AddToCache(bikesAvailableResponse, operatorUri);
Server.AddToCache(bikesOccupiedResponse);
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and occupied read successfully from server.");

View file

@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks;
using TINK.Model.Bikes;
using TINK.Model.Services.CopriApi;
@ -14,7 +15,8 @@ namespace TINK.Model.Connector
Task<Result<BikeCollection>> GetBikesOccupiedAsync();
/// <summary> Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in. </summary>
/// <param name="operatorUri">Uri of the operator host to get bikes from or null if bikes have to be gotten form primary host.</param>
/// <returns>Collection of bikes.</returns>
Task<Result<BikeCollection>> GetBikesAsync();
Task<Result<BikeCollection>> GetBikesAsync(Uri operatorUri = null);
}
}

Some files were not shown because too many files have changed in this diff Show more